I'm trying to learn how custom script actions work, but I ran into a problem. Here I have a script that I put together, but it won't show the parameters in the Action List at all. Also, the title in the custom script is 'untitled' and not as I wrote. Otherwise, the custom script is visible in the console.
I would like to control a robot on the nav mesh that has random movement and stop function!
A little help, Chris!? I'm using unity 2022.3.8f1 and AC v1.79.3
Here is the script:
using UnityEngine;
using System.Collections.Generic;
using AC;
using UnityEngine.AI;
using UnityEditor;
namespace AC
{
[System.Serializable]
public class ActionRandomNavMeshMovement : Action
{
// SerializeField ensures that the variables appear in the Inspector
[SerializeField] public float minSpeed = 1f;
[SerializeField] public float maxSpeed = 3f;
[SerializeField] public float minStopDuration = 1f;
[SerializeField] public float maxStopDuration = 3f;
[SerializeField] public AudioClip movingSound;
[SerializeField] public AudioClip stoppingSound;
// Private variables
private NavMeshAgent navMeshAgent;
private float currentSpeed;
private float currentStopDuration;
private float timer;
private AudioSource audioSource;
private bool isMoving = false;
// The execution function of the Action
public override float Run()
{
if (isRunning)
{
timer += Time.deltaTime;
if (timer >= currentStopDuration)
{
SetRandomStopDuration();
MoveToRandomDestination();
timer = 0f;
}
// Check if the object is moving and play the moving sound
if (navMeshAgent.velocity.magnitude > 0 && !isMoving)
{
isMoving = true;
audioSource.clip = movingSound;
audioSource.loop = true;
audioSource.Play();
}
// Check if the object is stopped and play the stopping sound
else if (navMeshAgent.velocity.magnitude == 0 && isMoving)
{
isMoving = false;
audioSource.clip = stoppingSound;
audioSource.loop = true;
audioSource.Play();
}
return defaultPauseTime;
}
else
{
return 0f;
}
}
// Initialize the action
public override void AssignValues(List<ActionParameter> parameters)
{
// Initialize variables
GameObject gameObject = KickStarter.sceneSettings.gameObject;
navMeshAgent = gameObject.GetComponent<NavMeshAgent>();
audioSource = gameObject.GetComponent<AudioSource>();
SetRandomSpeed();
SetRandomStopDuration();
MoveToRandomDestination();
}
void MoveToRandomDestination()
{
Vector3 randomDestination = RandomNavMeshLocation();
navMeshAgent.SetDestination(randomDestination);
}
Vector3 RandomNavMeshLocation()
{
Vector3 randomDirection = Random.insideUnitSphere * 10f;
randomDirection += KickStarter.sceneSettings.gameObject.transform.position;
NavMeshHit hit;
NavMesh.SamplePosition(randomDirection, out hit, 10f, NavMesh.AllAreas);
return hit.position;
}
void SetRandomSpeed()
{
currentSpeed = Random.Range(minSpeed, maxSpeed);
navMeshAgent.speed = currentSpeed;
}
void SetRandomStopDuration()
{
currentStopDuration = Random.Range(minStopDuration, maxStopDuration);
}
}
}
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
The main thing I'm seeing though is that it doesn't appear to need to actually be an Action - it would be better off adapted to a regular MonoBehaviour script, replacing Run with Update and then attach to the NPC you want to control.