- Home /
c# code help -- events part 1
got a few questions on coding, i'll just ask one at a time.
I would like, when the player walks in the field of view of the enemy, the enemy rushes at the player and then disappears, causing a raise in heart rate by 20 BPM.
I think events, PlayerInViewEvent, and RateIncreaseEvent are what would work for this. but i do not know how to get that all to work in the code, and i don't know if those are even the best way to go about this. Can i please get some coding help.
here is the code i have so far.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HeartRate : MonoBehaviour {
public GameObject Player;
public GameObject Enemy;
float heartRateBase = 80; // 80 BPM
public float heartRate = 100;
float safeDistance = 5; // distance away form the enemy where heart rate goes down
float relaxRate = 0.005f; // how fast the player recovers
float stressRate = 0.05f;// The closer the plauer is to the enemy the more it will increase
void FixedUpdate()
{
// Find distance from enemy
float dist = Vector3.Distance (Player.transform.position, Enemy.transform.position);
// Check to see if player is safe
if (dist > safeDistance)
{
// Decrease player heart Rate
if (heartRate > heartRateBase)
heartRate -= relaxRate;
}
else
{
// Increase the players heart rate depending on how close they are
float rate = 1 - dist / safeDistance;
heartRate += stressRate * rate;
}
}
}
why do you think you're supposed to use events? is this code working?
this code does work, but its only for when the player is close to the enemy. That is all the code i have so far. and i thought that events would be the best way to do what i need. Is an event not the right way to go about this?
Events build up too much garbage to want to run them constantly. They are very useful, but just remember not to abuse them.
So the enemy needs a controller script, that checks distance, and raycasts or linecasts a line of sight, then if it has a clear path, you can use your own movement system, or a Nav$$anonymous$$eshAgent to send the enemy toward to player, and if he is less than or equal to the attack or disappearing distance, that's when you make him disappear, and call the spike in heart rate.
To implement a UnityEvent, which let me be clear, is very different from a c# event.
public UnityEngine.Events.UnityEvent OnWhateverAction;
void Update()
{
if(blah >= blahblah)
{
OnWhateverAction.Invoke();
}
}
That is the absolute simplest way to implement events. Now, events can have parameters as well, and can even be tied to methods with parameters in the inspector.
As well, you can use the Action system to create our own types of event handlers. Basically an event works kind of like this...
public class Event
{
public List<Action> actions;
public Event()
{
actions = new List<Action>();
}
public void AddListener(Action action)
{
actions.Add(action);
}
public void RemoveListener(Action action)
{
actions.Remove(action);
}
public void Invoke()
{
foreach (Action action in actions)
{
action.Invoke();
}
}
}
Answer by NoMoneys · Mar 25, 2018 at 06:44 PM
You could use certain colliders as children of the enemy to represent it's field of view, then when the player enters one of these colliders you could make the enemy do something.
For example: You could use a state-machine for the enemy using an enum; whenever the player is in sight, change the state of the enemy to aggresive, and do something based on that state.
As for making it disappear when it gets within range, You could enable or disable the meshrenderer of the enemy component based on the distance to the player.
Thank you, that is a possible solution. as i am still new to coding, i don't know exactly how to make it actually work. Can you please give me an example of how i would do this?
This is how I would do it.
The enemy:
public class Enemy : $$anonymous$$onoBehaviour { public enum EnemyState { Nice, Aggresive }
public EnemyState currentState;
private void Update()
{
CheckStates();
}
private void CheckStates()
{
if(currentState == EnemyState.Nice)
{
// Do nice stuff
}
if(currentState == EnemyState.Aggresive)
{
// Do aggresive stuff
}
}
}
The enemy's collider (field of view in this case):
public class EnemyCollider : $$anonymous$$onoBehaviour { public Enemy masterObject;
public void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag == "Player")
{
masterObject.currentState = Enemy.EnemyState.Aggresive;
}
}
public void OnTriggerExit(Collider other)
{
if(other.gameObject.tag == "Player")
{
masterObject.currentState = Enemy.EnemyState.Nice;
}
}
}
The enemy collider changes the current state of the enemy (which I called masterObject). Then in the enemy script you can execute code based on the current state.
thank you, i really appreciate it. I've had a lot of problems with this. hopefully i can get this to work. i will try and tag you in any other questions if i need help with this further.
Your answer
