Thats for today i will do more tests tommorow just for any case but for today i call it a day, also it will get probably upgraded later when i finish my abilities tutorials and quests and shop tutorials etc , its up for discusions waiting to hear more ( print still exists because its still under construction so de bugging should exist , Yes for some reason i print instead of debugg.log.
First the base system of how stealth and perception works it can be upgraded aslo through some abilties passives etc that would come later when i reach and finish the Abilities course :
namespace RPG.Combat
{
public class StealthSystem : MonoBehaviour
{
[SerializeField] GameObject bodyAppear;
[SerializeField] bool canDetect = false;
[SerializeField]bool startsHiden = false;
[SerializeField] bool isStealth;
public bool IsStealth()
{
return isStealth;
}
float currentStealthVallue;
public float CurrentStealthVallue()
{
return currentStealthVallue;
}
[SerializeField] int testStealth;
float activeStealthVallue;
[SerializeField] int testPerception;
BaseStats stats;
private void Awake()
{
stats = GetComponent<BaseStats>();
}
// Start is called before the first frame update
void Start()
{
if (startsHiden)
{
Invoke("ActivateStealth", 0.1f);
}
}
// Update is called once per frame
void Update()
{
activeStealthVallue = GetInitialMaxStealth();
}
public float GetInitialMaxStealth()
{
return stats.GetStat(Stat.Dexterity) + testStealth;
}
public float GetInitialMaxPerception()
{
return stats.GetStat(Stat.Inteligence) + testPerception;
}
public void StealthTrigger()
{
if (isStealth)
{
DeactivateStealth();
print("my current stealth is :" + currentStealthVallue);
}
else
{
ActivateStealth();
print("my current stealth is :" + currentStealthVallue);
}
}
public void DeactivateStealth()
{
isStealth = false;
StealthBehavior();
}
public void ActivateStealth()
{
isStealth = true;
StealthBehavior();
}
void StealthBehavior()
{
if(this.gameObject.tag == "Player")
{
if (isStealth)
{
currentStealthVallue = activeStealthVallue;
return;
}
else
{
currentStealthVallue = 0;
}
return;
}
if (isStealth)
{
currentStealthVallue = activeStealthVallue;
bodyAppear.SetActive(false);
return;
}
currentStealthVallue = 0;
bodyAppear.SetActive(true);
}
public int PerceptionRoll()
{
return Random.Range(0, 10);
}
}
}
Now we want something that would make our enemies able to see us when the time is come :
IEnumerator PerceptionChecks()
{
float Detection = this.gameObject.GetComponent<StealthSystem>().GetInitialMaxPerception();
float Plstealth = player.GetComponent<StealthSystem>().CurrentStealthVallue();
int stealthFailedAttemps;
tryDetect = true;
print("player steath = " + Plstealth + " and my perception is =" + Detection );
for (stealthFailedAttemps = 0; Detection < Plstealth; stealthFailedAttemps++)
{
if(stealth.PerceptionRoll() + stealthFailedAttemps + Detection > Plstealth)
{
break;
}
else if(stealth.PerceptionRoll() + stealthFailedAttemps + Detection > Plstealth / 1.5f)
{
transform.LookAt(player.transform.position);
}
if (!IsAggrevated())
{
break;
}
print(" my roll would be :" + stealth.PerceptionRoll() + " i have failed to see you :" + stealthFailedAttemps);
Plstealth = player.GetComponent<StealthSystem>().CurrentStealthVallue();
yield return new WaitForSeconds(1.5f);
}
if (IsAggrevated())
{
print("I SEE YOU");
AttackBehaviour();
foundPlayer = true;
}
else
{
foundPlayer = false;
tryDetect = false;
print("it seems i was imagine things");
}
}
Also a diffrent aproach during aggrevated :
private void Update()
{
if (health.IsDead()) return;
if (IsAggrevated() && fighter.CanAttack(player))
{
if (foundPlayer)
{
AttackBehaviour();
return;
}
if (tryDetect)
{
return;
}
StartCoroutine(PerceptionChecks());
}
Now we wish an approach that would the play able to turn stealth but also a way that would prevent player turn stealth in the middle of a fight the way that i would stop player turn stealth in the middle of the fight is commented and not yet in game.
if (InteractiWithUI()) return;
if (health.IsDead())
{
if (stealth.IsStealth())
{
stealth.DeactivateStealth();
}
SetCursor(CursorType.None);
return;
}
if (Input.GetKeyDown(KeyCode.C))
{
if (stealth.IsStealth())
{
stealth.StealthTrigger();
return;
}
// going add an else if trigger that if play is inCombat wouldnt be able re activate stalth
else
{
stealth.StealthTrigger();
return;
}
}
However we want to make an sneak attack it could be extra damage or whatever but attacking should reveal your possiton so its time to implent that :
void Hit()
{
if (target == null) { return; }
if (stealth.IsStealth())
{
print(gameObject.name + " i sneak attack you");
stealth.DeactivateStealth();
}
float attackDamage = IntPower() + DexPower() + StrPower() + stats.GetStat(Stat.BonusDamage);
if(currentWeapon.value != null)
{
currentWeapon.value.OnHit();
}
if (currentWeaponConfig.HasProjectile())
{
currentWeaponConfig.LaunchProjectile(rightHandTransform, leftHandTransform, target, gameObject, attackDamage);
}
else
{
target.TakeDamage(gameObject, attackDamage);
}
}
and now if you take damage you must stoped being stealth so its time to make that happens :
public void TakeDamage(GameObject instigator, float damage)
{
float Hplost;
Hplost = damage - armor;
if(Hplost < 1)
{
Hplost = 1;
}
currentHealth = Mathf.Max(currentHealth - Hplost, 0);
if (stealth.IsStealth())
{
stealth.DeactivateStealth();
}
if (IsDead())
{
onDie.Invoke();
Die();
AwardExperiance(instigator);
}
else
{
takeDamage.Invoke(Hplost);
}
}
Now the next step is making player able to detect hiden enemies or even objects. For objects thing a little change on the stealth system maybe exist or a new script that inherits from stealthsystem named as hiddenObjects maybe come that would the players perception make reveal them ( turning their stealth off) , also i would try make the raycast not trigger while mouse pass over a stealth enemy or object.
two screenshots about stealth enemies
and appearance when you hit them:
the fireball travels to the enemy ( unseing enemy)
the fireball hits the enemy and the enemy appears :
if you wish to see what happens when i am close at enemies at stealth i can post more etc. Thanks a lot in advance