Working gardener chase without flipping

This commit is contained in:
2025-09-19 15:51:50 +02:00
parent e1ee73bfb4
commit 6abf25b2ad
9 changed files with 2591 additions and 1234 deletions

View File

@@ -79,7 +79,7 @@ AnimationClip:
m_Level: 0
m_CycleOffset: 0
m_HasAdditiveReferencePose: 0
m_LoopTime: 0
m_LoopTime: 1
m_LoopBlend: 0
m_LoopBlendOrientation: 0
m_LoopBlendPositionY: 0

View File

@@ -52,7 +52,7 @@ AnimatorStateMachine:
m_StateMachineTransitions: {}
m_StateMachineBehaviours: []
m_AnyStatePosition: {x: 50, y: 20, z: 0}
m_EntryPosition: {x: 50, y: 120, z: 0}
m_EntryPosition: {x: 80, y: 130, z: 0}
m_ExitPosition: {x: 800, y: 120, z: 0}
m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
m_DefaultState: {fileID: 1953973717063047684}
@@ -92,7 +92,7 @@ AnimatorState:
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: ANIM_Gardener_Chase
m_Speed: 1
m_Speed: 0.5
m_CycleOffset: 0
m_Transitions:
- {fileID: -2076711753281386268}
@@ -191,11 +191,11 @@ AnimatorStateTransition:
m_Mute: 0
m_IsExit: 0
serializedVersion: 3
m_TransitionDuration: 0.25
m_TransitionDuration: 0
m_TransitionOffset: 0
m_ExitTime: 0.75409836
m_HasExitTime: 1
m_HasFixedDuration: 1
m_HasExitTime: 0
m_HasFixedDuration: 0
m_InterruptionSource: 0
m_OrderedInterruption: 1
m_CanTransitionToSelf: 1

View File

@@ -13,6 +13,7 @@ MonoBehaviour:
m_Name: DefaultSettings
m_EditorClassIdentifier:
playerStopDistance: 10
playerStopDistanceDirectInteraction: 2
followerPickupDelay: 0.2
followDistance: 5
manualMoveSmooth: 2
@@ -20,7 +21,7 @@ MonoBehaviour:
thresholdNear: 7
stopThreshold: 0.5
moveSpeed: 25
stopDistance: 0.1
stopDistance: 2
useRigidbody: 1
defaultHoldMovementMode: 1
followUpdateInterval: 0.1

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
using UnityEngine;
using Pixelplacement;
using Pixelplacement.TweenSystem;
public class GardenerChaseBehavior : MonoBehaviour
{
@@ -7,10 +8,33 @@ public class GardenerChaseBehavior : MonoBehaviour
public Transform GardenerObject;
public float chaseDuration;
public float chaseDelay;
[SerializeField] private Animator animator;
[SerializeField] public GameObject lawnMowerRef;
private TweenBase tweenRef;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
Tween.Spline (ChaseSpline, GardenerObject, 0, 1, false, chaseDuration, chaseDelay, Tween.EaseInOut, Tween.LoopType.PingPong);
tweenRef = Tween.Spline (ChaseSpline, GardenerObject, 0, 1, false, chaseDuration, chaseDelay, Tween.EaseLinear, Tween.LoopType.None, HandleTweenStarted, HandleTweenFinished);
}
void HandleTweenFinished ()
{
//Debug.Log ("Tween finished!");
tweenRef.Stop();
Destroy(ChaseSpline);
var gardenerSpriteRef = gameObject.transform.Find("GardenerRunningSprite");
//ReparentWithExactWorldTransform(gardenerSpriteRef, lawnMowerRef.transform);
gardenerSpriteRef.transform.SetParent(lawnMowerRef.transform, true);
//Vector3 pos = gardenerSpriteRef.position;
//pos.y = lawnMowerRef.transform.position.y;
//gardenerSpriteRef.position = pos;
}
void HandleTweenStarted ()
{
//Debug.Log ("Tween started!");
animator.SetBool("IsIdle?", false);
}
void Awake()
@@ -23,4 +47,34 @@ public class GardenerChaseBehavior : MonoBehaviour
{
}
public void ReparentWithExactWorldTransform(Transform objectToMove, Transform newParent)
{
// Store the original world position, rotation, and scale
Vector3 originalWorldPosition = objectToMove.position;
Quaternion originalWorldRotation = objectToMove.rotation;
Vector3 originalWorldScale = objectToMove.lossyScale;
// First change the parent
objectToMove.SetParent(newParent, false); // Set worldPositionStays to false
// Then manually restore world position and rotation
objectToMove.position = originalWorldPosition;
objectToMove.rotation = originalWorldRotation;
// Correct the scale (this is tricky because localScale isn't the same as world scale)
if (newParent != null)
{
Vector3 newLocalScale = objectToMove.localScale;
Vector3 parentWorldScale = newParent.lossyScale;
// Adjust local scale to maintain world scale
newLocalScale.x = (Mathf.Approximately(parentWorldScale.x, 0f)) ? 0f : originalWorldScale.x / parentWorldScale.x;
newLocalScale.y = (Mathf.Approximately(parentWorldScale.y, 0f)) ? 0f : originalWorldScale.y / parentWorldScale.y;
newLocalScale.z = (Mathf.Approximately(parentWorldScale.z, 0f)) ? 0f : originalWorldScale.z / parentWorldScale.z;
objectToMove.localScale = newLocalScale;
}
}
}

View File

@@ -1,13 +1,15 @@
using UnityEngine;
using System.Security.Cryptography.X509Certificates;
using Pixelplacement;
using UnityEngine;
public class GardenerBehaviour : MonoBehaviour
{
private StateMachine stateMachineRef;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
stateMachineRef = GetComponent<StateMachine>();
}
// Update is called once per frame
@@ -15,4 +17,10 @@ public class GardenerBehaviour : MonoBehaviour
{
}
public void stateSwitch (string StateName)
{
Debug.Log("State Switch to: " + StateName);
stateMachineRef.ChangeState(StateName);
}
}

View File

@@ -7,63 +7,123 @@ public class LawnMowerChaseBehaviour : MonoBehaviour
public Transform LawnMowerObject;
public float chaseDuration;
public float chaseDelay;
[Range(0, 1)] public float startPercentage; // Exposed in Inspector
private Vector3 _originalScale;
private bool _facingRight = true;
private bool _movingForward = true;
private float _lastPercentage = 0f;
private const float AnchorThreshold = 0.1f; // Tolerance for anchor detection
private const float AnchorThreshold = 0.05f;
private bool _wasAtStart = false;
private bool _wasAtEnd = false;
// For initial tween tracking
private bool _initialTweenActive = true;
private float _initialTargetAnchor = 1f;
void Start()
{
_originalScale = LawnMowerObject.localScale;
LawnMowerObject.position = ChaseSpline.GetPosition(startPercentage);
float distanceToStart = Mathf.Abs(startPercentage - 0f);
float distanceToEnd = Mathf.Abs(startPercentage - 1f);
if (distanceToStart < distanceToEnd)
{
// Tween from startPercentage to 1
_initialTargetAnchor = 1f;
Tween.Spline(
ChaseSpline,
LawnMowerObject,
startPercentage,
1,
false,
chaseDuration * (1 - startPercentage),
chaseDelay,
Tween.EaseInOut,
Tween.LoopType.None
);
}
else
{
// Tween from startPercentage to 0
_initialTargetAnchor = 0f;
Tween.Spline(
ChaseSpline,
LawnMowerObject,
startPercentage,
0,
false,
chaseDuration * startPercentage,
chaseDelay,
Tween.EaseInOut,
Tween.LoopType.None
);
}
_initialTweenActive = true;
}
void Update()
{
float percentage = ChaseSpline.ClosestPoint(LawnMowerObject.position);
// Handle initial tween completion
if (_initialTweenActive)
{
if (Mathf.Abs(percentage - _initialTargetAnchor) <= AnchorThreshold)
{
// Start ping-pong tween between extremes
StartPingPongTween(_initialTargetAnchor, 1f - _initialTargetAnchor);
_initialTweenActive = false;
}
return; // Don't process flip logic until ping-pong starts
}
// Detect start anchor
if (percentage <= AnchorThreshold)
{
if (!_wasAtStart)
{
flipSprite();
_wasAtStart = true;
_wasAtEnd = false;
}
}
// Detect end anchor
else if (percentage >= 1f - AnchorThreshold)
{
if (!_wasAtEnd)
{
flipSprite();
_wasAtEnd = true;
_wasAtStart = false;
}
}
else
{
_wasAtStart = false;
_wasAtEnd = false;
}
}
private void StartPingPongTween(float from, float to)
{
Tween.Spline(
ChaseSpline,
LawnMowerObject,
0,
1,
from,
to,
false,
chaseDuration,
chaseDelay,
0,
Tween.EaseInOut,
Tween.LoopType.PingPong,
onComplete: OnTweenComplete
Tween.LoopType.PingPong
);
}
private void OnTweenComplete()
private void flipSprite()
{
_movingForward = !_movingForward;
Flip(_movingForward);
Vector3 scale = LawnMowerObject.transform.localScale;
Vector3 rotation = LawnMowerObject.transform.eulerAngles;
scale.x *= -1;
rotation.z *= -1;
LawnMowerObject.transform.localScale = scale;
LawnMowerObject.transform.eulerAngles = rotation;
}
private void OnTweenUpdate()
{
// Find the current percentage along the spline
float percentage = ChaseSpline.ClosestPoint(LawnMowerObject.position);
// Detect anchor arrival and flip accordingly
if (_facingRight && percentage >= 1f - AnchorThreshold)
{
Flip(false); // Face left at end anchor
_facingRight = false;
}
else if (!_facingRight && percentage <= AnchorThreshold)
{
Flip(true); // Face right at start anchor
_facingRight = true;
}
_lastPercentage = percentage;
}
private void Flip(bool faceRight)
{
var scale = _originalScale;
scale.x = Mathf.Abs(scale.x) * (faceRight ? 1 : -1);
LawnMowerObject.localScale = scale;
}
void Update() { }
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1fda7fccaa5fbd04695f4c98d29bcbe0
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: