- Home /
How would you code a Wind script?
Hi! I have a simple player movement script where I manually set the velocity of the player's rigidbody. I am not using Rigidbody.AddForce() because I found it doesn't feel right for my type of game.
Now, in some of the levels I have what I call "wind zones" where an external force needs to be applied to the player based on the wind strength and the distance from the center of the wind as long as the player is inside the wind zone.
The question is, how would you program the wind zone? I would like to keep the wind zone as separate from the player as possible.
I could for example check if the player is inside of a wind zone in the player's script and and set the velocity vector accordingly, but then I have no code separation.
I also though about a Composition model, where an external force script is added to the player when the wind zone is entered. That way the force script will manipulate the player's velocity in the Update method. But which Update is called first, the player's Update or the force's Update? Is the order guaranteed? The fact there needs to be a specific order for it to works makes me think it's not a good idea. I would also like to be able to add the force script to any other object in the scene, so this approach is not good either.
I also though about a MovementModule mode, where I have a generic Movement Script and I plug in different movement modules, like wind zones, water etc. These modules should determine the velocity to assign to the player on each frame. But what if I have a wind zone in the water? Then only one module can work...
I am clearly confused, so if you also have any material where I can learn more about these things I would be very thankful!
Thank you.
Answer by CiberX15 · Apr 22, 2020 at 03:34 AM
What I would do in this scenario is make a game object with a trigger. Then use OnTriggerStay() to find all objects currently inside the trigger. Then add velocity to any that have Rigidbodies. This also has the advantage of being completely independent of the player logic, and would work on any physics object that came into the wind area for a more consistent behavior (though you could check specifically for the player if you didn't want other objects to be effected). Something like this:
private void OnTriggerStay(Collider other)
{
Rigidbody hitR = other.gameObject.GetComponent<Rigidbody>();
if(hitR != null)
{
hitR.velocity += windVelocity;
}
}
Now that would get overwritten if you are setting the players velocity every frame so you might still have to make some modifications to the player. In that case I would add a vector3 windvelocity variable to the player and instead of having the wind script add to velocity have it set that windvelocity varable. Then your player script could add windvelocity to the set velocity. Then zero the windvelocity. That should prevent order of operations issues since the windvelicty is only zeroed after it has been used, and it is only populated when the player is in the wind trigger area. in which case the wind code might look more like this:
private void OnTriggerStay(Collider other)
{
Player hitPlayer = other.gameObject.GetComponent<Player>();
if (hitPlayer != null)
{
hitPlayer.windVelocity = windVelocity
}
else
{
Rigidbody hitR = other.gameObject.GetComponent<Rigidbody>();
if (hitR != null)
{
hitR.velocity += windVelocity;
}
}
}
And then in player script:
void Update()
{
//Whatever your movement code does...
velocity += windVelocity;
windVelocity = vector3.zero;
}
Finally while I don't think you should need to guarantee update order in this case since there are other ways to avoid the order of operation issues, it is possible if you need to for some other reason: https://docs.unity3d.com/Manual/class-MonoManager.html