I am attempting to develop a C# script that does the following:
I want to record where the gameObject, in this case a large spider in the 3D world on a Unity terrain, begins. I want to set the direction random and translate movement 1 meter away from center location. When greater than 1 meter away I want to turn around and go to center location/start location and randomize/repeat again.
Can you guys and gals help me fix my bad attempt at writing this in C#?
I think I’m accidentally updating direction every single frame.
After I understand how wrong I am I’m probably going to alter the 1 meter value in the script to randomize between values or be set in inspector for random range of values, then if the range is 1 to 2 it’ll go randomly 1.x meters away, return, and then do another calculation for x, direction, and repeat movement.
Thank you!
Have a great day!
Here’s a video!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WanderImp : MonoBehaviour
{
private bool outwardMovementFlag;
private bool randomizeFlag;
private Vector3 wanderCentroid;
public float speed = 3.0f;
public float rotateSpeed = 3.0f;
public float dist;
public CharacterController controller;
private void Awake()
{
outwardMovementFlag = true;//true means yes move outward
randomizeFlag = true;
wanderCentroid = transform.position;
controller = GetComponent<CharacterController>();
}
private void Update()
{
//psudocode...
//if the flag to indicate a move outward from central point is true,
//move outward until 1 meter away from central point
//once 1 meter out from central point turn around,
//move back to central point
//this isn't quite working out...
if (outwardMovementFlag)
{
if (randomizeFlag)
{
transform.Rotate(0.0f, Random.Range(0.0f, 360.0f), 0.0f);
}
Vector3 forward = transform.TransformDirection(Vector3.forward);
controller.SimpleMove(forward);
dist = Vector3.Distance(this.gameObject.transform.position, wanderCentroid);
if (dist >= 1.0f)
{
outwardMovementFlag = false;
}
randomizeFlag = false;
}
else
{
transform.Rotate(0.0f, wanderCentroid.y, 0.0f);
Vector3 forward = transform.TransformDirection(Vector3.forward);
controller.SimpleMove(forward);
if (dist <= 0.05f)
{
outwardMovementFlag = true;
}
randomizeFlag = true;
}
}
}
Might be best to set this up by giving the spider a desiredPosition.
Then your script would have two parts:
The Movement Agent:
The spider would compare its currentPosition to the desiredPosition and if there is any difference, turn and move a little bit. If he was close enough he’d stop and set a flag.
The Destination Chooser:
Then, completely separate from that code, you could check the above flag and decide if they should be back to center or back to a new radial (alternating). If it is time, set the new desiredPosition, either to a radial or to the center and wait.
For picking a random direction, just do:
var heading = Random.Range( 0.0f, 360.0f);
var offset = Quaternion.Euler( 0, heading, 0) * Vector3.forward;
I love using that “desired versus current setup” for tons of things that need to gradually change over time. You can use it for floats, ints, Vector3s, (any Vector!) etc. and the concept remains ultra simple and understandable.
This is great! I am going to implement this over a bottle of water, reducing my caffeine intake.
It sounds like you’re helping me put the code into a sort of state machine with two states. I am starting to wrap my head around this whole scripting thing, but it’s funny I feel like I understand so well until I write my own algorithms like this!