Unity-WebSocket/Assets/FishNet/Demos/Benchmarks/NetworkTransform/Scripts/MoveRandomlyNonPhysics.cs
2025-06-28 11:28:54 +03:30

214 lines
6.0 KiB
C#

using System;
using System.Collections.Generic;
using FishNet.Utility.Template;
using UnityEngine;
using Random = UnityEngine.Random;
namespace FishNet.Demo.Benchmarks.NetworkTransforms
{
public class MoveRandomlyNonPhysics : TickNetworkBehaviour
{
[System.Serializable]
private struct GoalData
{
public Vector3 Position;
public Vector3 Eulers;
}
[SerializeField]
private bool _isActive = true;
[SerializeField]
private bool _is2d;
[Header("Changes")]
[SerializeField]
[Range(0, 3)]
private byte _axes = 3;
[Range(0.1f, 1f)]
[SerializeField]
private float _chancePerAxes = 0.8f;
[SerializeField]
[Range(0f, 1f)]
private float _rotationChance = 0.33f;
[Header("Movement")]
[Range(0f, 5f)]
[SerializeField]
private float _delayBetweenMovements = 1.5f;
[SerializeField]
private float _yOffsetPerInstance = 0f;
[SerializeField]
private bool _randomMovement = true;
[SerializeField]
private List<GoalData> _goalDatas = new();
[SerializeField]
private bool _moveInUpdate = false;
[SerializeField]
[Range(0.1f, 30f)]
private float _moveRate = 3f;
[Range(1f, 30f)]
[SerializeField]
private float _rotateRate = 30f;
[Range(0.1f, 40f)]
[SerializeField]
private float _range = 6f;
//Position to move towards.
private Vector3 _goalPosition;
//Rotation to move towards.
private Quaternion _goalRotation;
private Quaternion _lastRot;
private int _nextGoalDataIndex = 0;
private float _nextMoveTime = float.MinValue;
public override void OnStartNetwork()
{
if (!base.IsServerStarted && !base.Owner.IsLocalClient)
{
base.SetTickCallbacks(TickCallback.None);
DestroyImmediate(this);
}
else
{
if (_moveInUpdate)
base.SetTickCallbacks(TickCallback.Update);
else
base.SetTickCallbacks(TickCallback.Tick);
}
}
protected override void TimeManager_OnUpdate()
{
if (_moveInUpdate)
Move(Time.deltaTime);
}
protected override void TimeManager_OnTick()
{
if (!_moveInUpdate)
{
float delta = (float)base.TimeManager.TickDelta;
Move(delta);
}
}
private void Move(float delta)
{
if (!_isActive)
return;
if (!base.IsController)
return;
if (Time.time < _nextMoveTime)
return;
transform.position = Vector3.MoveTowards(transform.position, _goalPosition, _moveRate * delta);
if (!_is2d)
transform.rotation = Quaternion.RotateTowards(transform.rotation, _goalRotation, _rotateRate * delta);
else
transform.rotation = _goalRotation;
if (transform.position == _goalPosition)
SetNextGoal();
}
public override void OnStartServer()
{
TrySetFirstGoal();
}
public override void OnStartClient()
{
TrySetFirstGoal();
}
private void TrySetFirstGoal()
{
if (!base.IsController)
return;
SetNextGoal();
transform.position = _goalPosition;
transform.rotation = _goalRotation;
_nextMoveTime = float.MinValue;
}
private void SetNextGoal()
{
if (_randomMovement)
SetRandomGoal();
else
SetSpecifiedGoal();
_nextMoveTime = Time.time + _delayBetweenMovements;
void SetSpecifiedGoal()
{
if (_goalDatas.Count == 0) return;
if (_nextGoalDataIndex >= _goalDatas.Count)
_nextGoalDataIndex = 0;
int index = _nextGoalDataIndex;
_nextGoalDataIndex++;
_goalPosition = _goalDatas[index].Position;
_goalRotation = Quaternion.Euler(_goalDatas[index].Eulers);
}
void SetRandomGoal()
{
if (_axes > 0)
{
Vector3 rnd = (Random.insideUnitSphere * _range);
Vector3 next = transform.position;
if (_axes >= 1 && RandomizeAxes())
next.x = rnd.x;
if (_axes >= 2 && RandomizeAxes())
next.y = rnd.y;
if (_axes >= 3 && RandomizeAxes())
next.z = rnd.z;
//Make sure at least one axes is set.
if (next == transform.position)
next.x = rnd.x;
bool RandomizeAxes() => (Random.Range(0f, 1f) <= _chancePerAxes);
_goalPosition = next;
}
if (_rotationChance > 0f)
{
if (Random.Range(0f, 1f) <= _rotationChance)
{
Vector3 euler;
if (!_is2d)
{
euler = Random.insideUnitSphere * 180f;
}
else
{
float nextY = (transform.eulerAngles.y == 0f) ? 180f : 0f;
euler = new Vector3(0f, nextY, 0f);
}
_goalRotation = Quaternion.Euler(euler);
}
else
{
_goalRotation = transform.rotation;
}
}
}
}
}
}