You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
5.1 KiB
C#
174 lines
5.1 KiB
C#
using UnityEngine;
|
|
using DG.Tweening;
|
|
using UnityEngine.Animations;
|
|
|
|
public class CharacterMovement : MonoBehaviour
|
|
{
|
|
public enum MovementState { Walking, RotatingToSit, PlayingAnimation, Finished }
|
|
public MovementState state = MovementState.Walking;
|
|
|
|
[Header("Waypoints")]
|
|
public Transform[] waypoints;
|
|
private int currentWaypoint = 0;
|
|
|
|
[Header("References")]
|
|
public GameObject rigWithAnimator;
|
|
public Animator animator;
|
|
public CameraController cameraController;
|
|
public CameraHeadBobbing cameraHeadBobbing;
|
|
public Transform mainCamera; // Camera.main.transform
|
|
public Transform cameraSitTarget; // Dummy camera transform
|
|
|
|
[Header("Settings")]
|
|
public float moveSpeed = 2f;
|
|
public float rotationSpeed = 5f;
|
|
private string currentAnimName = "";
|
|
private bool animStarted = false;
|
|
private bool cameraTransitionStarted = false;
|
|
private Quaternion targetSitRotation;
|
|
bool isStarted = false;
|
|
void Start()
|
|
{
|
|
if (waypoints == null || waypoints.Length == 0)
|
|
{
|
|
Debug.LogError("No waypoints assigned.");
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
if (animator == null && rigWithAnimator != null)
|
|
{
|
|
animator = rigWithAnimator.GetComponentInChildren<Animator>();
|
|
}
|
|
|
|
if (animator == null)
|
|
{
|
|
Debug.LogError("Animator not found.");
|
|
enabled = false;
|
|
return;
|
|
}
|
|
|
|
animator.applyRootMotion = false;
|
|
}
|
|
public void AnimationStarter()
|
|
{
|
|
animator.SetTrigger("StartWalking");
|
|
isStarted = true;
|
|
SupabaseEventLogger.Instance?.StartSession();
|
|
InstructionManager.Instance?.ShowScreenInstruction("mission_intro");
|
|
}
|
|
void Update()
|
|
{
|
|
if (isStarted)
|
|
{
|
|
switch (state)
|
|
{
|
|
case MovementState.Walking:
|
|
MoveToWaypoint();
|
|
break;
|
|
|
|
case MovementState.RotatingToSit:
|
|
RotateToSit();
|
|
break;
|
|
|
|
case MovementState.PlayingAnimation:
|
|
WaitForAnimationToEnd();
|
|
break;
|
|
|
|
case MovementState.Finished:
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void MoveToWaypoint()
|
|
{
|
|
if (currentWaypoint >= waypoints.Length)
|
|
{
|
|
state = MovementState.Finished;
|
|
return;
|
|
}
|
|
|
|
Transform target = waypoints[currentWaypoint];
|
|
Vector3 direction = target.position - transform.position;
|
|
direction.y = 0;
|
|
|
|
if (direction.magnitude > 0.05f)
|
|
{
|
|
transform.position += direction.normalized * moveSpeed * Time.deltaTime;
|
|
|
|
Quaternion lookRot = Quaternion.LookRotation(direction);
|
|
transform.rotation = Quaternion.Slerp(transform.rotation, lookRot, rotationSpeed * Time.deltaTime);
|
|
}
|
|
else
|
|
{
|
|
if (currentWaypoint == waypoints.Length - 1)
|
|
{
|
|
// Prepare to sit
|
|
transform.position = target.position;
|
|
targetSitRotation = target.rotation;
|
|
state = MovementState.RotatingToSit;
|
|
}
|
|
currentWaypoint++;
|
|
}
|
|
}
|
|
|
|
void RotateToSit()
|
|
{
|
|
transform.rotation = Quaternion.RotateTowards(
|
|
transform.rotation,
|
|
targetSitRotation,
|
|
300f * Time.deltaTime
|
|
);
|
|
|
|
float angle = Quaternion.Angle(transform.rotation, targetSitRotation);
|
|
if (angle < 2f)
|
|
{
|
|
transform.rotation = targetSitRotation;
|
|
animator.applyRootMotion = true;
|
|
PlayAnimation("SitDown");
|
|
|
|
// Disable camera bobbing
|
|
if (cameraHeadBobbing != null)
|
|
cameraHeadBobbing.enabled = false;
|
|
|
|
state = MovementState.PlayingAnimation;
|
|
}
|
|
}
|
|
|
|
void PlayAnimation(string animName)
|
|
{
|
|
animator.SetTrigger(animName);
|
|
currentAnimName = animName;
|
|
animStarted = false;
|
|
}
|
|
|
|
void WaitForAnimationToEnd()
|
|
{
|
|
AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
|
|
|
|
if (!animStarted && stateInfo.IsName(currentAnimName))
|
|
{
|
|
animStarted = true;
|
|
}
|
|
else if (animStarted && stateInfo.normalizedTime >= 1f && stateInfo.IsName(currentAnimName))
|
|
{
|
|
if (currentAnimName == "SitDown" && !cameraTransitionStarted && mainCamera != null && cameraSitTarget != null)
|
|
{
|
|
cameraTransitionStarted = true;
|
|
|
|
// Move and rotate camera to final cinematic zoom position
|
|
mainCamera.GetComponent<LookAtConstraint>().constraintActive = false;
|
|
mainCamera.DOMove(cameraSitTarget.position, 1f);
|
|
mainCamera.DORotate(cameraSitTarget.eulerAngles, 1f)
|
|
.OnComplete(() =>
|
|
{
|
|
state = MovementState.Finished;
|
|
InstructionManager.Instance?.ShowScreenInstruction("click_to_open");
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|