[Player] Add simple Pulver point-based following behind Trafalgar. Leave option for manually-directed movement.
This commit is contained in:
@@ -15,9 +15,9 @@ GameObject:
|
|||||||
- component: {fileID: 2999879259114430221}
|
- component: {fileID: 2999879259114430221}
|
||||||
- component: {fileID: 7393789300602426170}
|
- component: {fileID: 7393789300602426170}
|
||||||
- component: {fileID: 1676944588148945034}
|
- component: {fileID: 1676944588148945034}
|
||||||
m_Layer: 0
|
m_Layer: 7
|
||||||
m_Name: PlayerCharacter
|
m_Name: PlayerCharacter
|
||||||
m_TagString: Untagged
|
m_TagString: Player
|
||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
m_NavMeshLayer: 0
|
m_NavMeshLayer: 0
|
||||||
m_StaticEditorFlags: 0
|
m_StaticEditorFlags: 0
|
||||||
@@ -221,6 +221,10 @@ PrefabInstance:
|
|||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: Trafalgar
|
value: Trafalgar
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 784715772773378889, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
|
||||||
|
propertyPath: m_Layer
|
||||||
|
value: 7
|
||||||
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7877460049793670011, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
|
- target: {fileID: 7877460049793670011, guid: 361ccc9ef82acef4784b24b72013d971, type: 3}
|
||||||
propertyPath: m_LocalScale.x
|
propertyPath: m_LocalScale.x
|
||||||
value: 0.5
|
value: 0.5
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ GameObject:
|
|||||||
- component: {fileID: 6668392923879433376}
|
- component: {fileID: 6668392923879433376}
|
||||||
- component: {fileID: 2732140975288177209}
|
- component: {fileID: 2732140975288177209}
|
||||||
- component: {fileID: 566650525959955209}
|
- component: {fileID: 566650525959955209}
|
||||||
m_Layer: 0
|
- component: {fileID: 7160527734420460260}
|
||||||
|
m_Layer: 8
|
||||||
m_Name: PulverCharacter
|
m_Name: PulverCharacter
|
||||||
m_TagString: Untagged
|
m_TagString: Untagged
|
||||||
m_Icon: {fileID: 0}
|
m_Icon: {fileID: 0}
|
||||||
@@ -125,3 +126,24 @@ SpriteRenderer:
|
|||||||
m_WasSpriteAssigned: 1
|
m_WasSpriteAssigned: 1
|
||||||
m_MaskInteraction: 0
|
m_MaskInteraction: 0
|
||||||
m_SpriteSortPoint: 0
|
m_SpriteSortPoint: 0
|
||||||
|
--- !u!114 &7160527734420460260
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 1102468210854536367}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: f82afe7b57bd4e0b9f51a1cca06765f1, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
followDistance: 2
|
||||||
|
debugDrawTarget: 1
|
||||||
|
followUpdateInterval: 0.1
|
||||||
|
manualMoveSmooth: 5
|
||||||
|
acceleration: 10
|
||||||
|
deceleration: 12
|
||||||
|
thresholdFar: 5
|
||||||
|
thresholdNear: 3
|
||||||
|
stopThreshold: 0.25
|
||||||
|
|||||||
@@ -495,11 +495,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: -4.53
|
value: -8.54
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: -0.5
|
value: -1.01
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -552,11 +552,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: 4.49
|
value: 5.6
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 3.49
|
value: 4.5
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -614,11 +614,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: -1.42
|
value: -4.43
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: 3.37
|
value: 6.43
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
- target: {fileID: 7046219584904338117, guid: 5e0579453a4cbae438cf2422f6786a48, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
@@ -22743,11 +22743,11 @@ PrefabInstance:
|
|||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
|
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
|
||||||
propertyPath: m_LocalPosition.x
|
propertyPath: m_LocalPosition.x
|
||||||
value: -3.03
|
value: -2.83
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
|
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
|
||||||
propertyPath: m_LocalPosition.y
|
propertyPath: m_LocalPosition.y
|
||||||
value: -1.2
|
value: -1.89
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
|
- target: {fileID: 6668392923879433376, guid: e3b439d398cffdd4194cdb360a46c5a6, type: 3}
|
||||||
propertyPath: m_LocalPosition.z
|
propertyPath: m_LocalPosition.z
|
||||||
|
|||||||
@@ -1 +1,148 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using Pathfinding;
|
||||||
|
|
||||||
|
public class FollowerController : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("Follower Settings")]
|
||||||
|
public float followDistance = 1.5f; // Desired distance behind player
|
||||||
|
public bool debugDrawTarget = true;
|
||||||
|
public float followUpdateInterval = 0.1f; // How often to update follow logic
|
||||||
|
public float manualMoveSmooth = 8f; // Smoothing factor for manual movement
|
||||||
|
|
||||||
|
private Transform playerTransform;
|
||||||
|
private AIPath playerAIPath;
|
||||||
|
private AIPath aiPath;
|
||||||
|
private Vector3 targetPoint;
|
||||||
|
private float timer;
|
||||||
|
private bool usePathfinding = false;
|
||||||
|
private bool isManualFollowing = true; // Default to manual following
|
||||||
|
private Vector3 lastMoveDir = Vector3.right; // Default direction
|
||||||
|
private float currentSpeed = 0f;
|
||||||
|
|
||||||
|
[Header("Speed Settings")]
|
||||||
|
public float acceleration = 10f;
|
||||||
|
public float deceleration = 12f;
|
||||||
|
public float thresholdFar = 2.5f;
|
||||||
|
public float thresholdNear = 0.5f;
|
||||||
|
public float stopThreshold = 0.1f; // Stop moving when within this distance
|
||||||
|
private float playerMaxSpeed = 5f;
|
||||||
|
|
||||||
|
void Awake()
|
||||||
|
{
|
||||||
|
aiPath = GetComponent<AIPath>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
// Find player by tag
|
||||||
|
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
|
||||||
|
if (playerObj != null)
|
||||||
|
{
|
||||||
|
playerTransform = playerObj.transform;
|
||||||
|
playerAIPath = playerObj.GetComponent<AIPath>();
|
||||||
|
// Fetch player's max speed
|
||||||
|
if (playerAIPath != null)
|
||||||
|
{
|
||||||
|
playerMaxSpeed = playerAIPath.maxSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("FollowerController: Player object with tag 'Player' not found.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateFollowTarget()
|
||||||
|
{
|
||||||
|
// Determine direction: use player's velocity if available, else lastMoveDir
|
||||||
|
Vector3 playerPos = playerTransform.position;
|
||||||
|
Vector3 moveDir = Vector3.zero;
|
||||||
|
if (playerAIPath != null && playerAIPath.velocity.magnitude > 0.01f)
|
||||||
|
{
|
||||||
|
moveDir = playerAIPath.velocity.normalized;
|
||||||
|
lastMoveDir = moveDir; // Update last valid direction
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moveDir = lastMoveDir; // Use last direction if stationary
|
||||||
|
}
|
||||||
|
// Calculate target point behind player
|
||||||
|
targetPoint = playerPos - moveDir * followDistance;
|
||||||
|
targetPoint.z = 0; // For 2D
|
||||||
|
|
||||||
|
// Always use manual following unless GoToPoint is called
|
||||||
|
isManualFollowing = true;
|
||||||
|
if (aiPath != null)
|
||||||
|
{
|
||||||
|
aiPath.enabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update()
|
||||||
|
{
|
||||||
|
if (playerTransform == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
timer += Time.deltaTime;
|
||||||
|
if (timer >= followUpdateInterval)
|
||||||
|
{
|
||||||
|
timer = 0f;
|
||||||
|
UpdateFollowTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manual movement logic with acceleration/deceleration and stop threshold
|
||||||
|
if (isManualFollowing)
|
||||||
|
{
|
||||||
|
float dist = Vector3.Distance(transform.position, targetPoint);
|
||||||
|
if (dist > stopThreshold)
|
||||||
|
{
|
||||||
|
float desiredSpeed = playerMaxSpeed;
|
||||||
|
if (dist > thresholdFar)
|
||||||
|
{
|
||||||
|
// Accelerate to player's max speed
|
||||||
|
desiredSpeed = Mathf.Min(currentSpeed + acceleration * Time.deltaTime, playerMaxSpeed);
|
||||||
|
}
|
||||||
|
else if (dist <= thresholdNear && dist > stopThreshold)
|
||||||
|
{
|
||||||
|
// Decelerate as approaching target, but keep moving until stopThreshold
|
||||||
|
desiredSpeed = Mathf.Max(currentSpeed - deceleration * Time.deltaTime, 0.5f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Maintain player's max speed
|
||||||
|
desiredSpeed = playerMaxSpeed;
|
||||||
|
}
|
||||||
|
currentSpeed = desiredSpeed;
|
||||||
|
Vector3 dir = (targetPoint - transform.position).normalized;
|
||||||
|
transform.position += dir * currentSpeed * Time.deltaTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Stop moving when close enough
|
||||||
|
currentSpeed = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Command follower to go to a specific point (pathfinding mode)
|
||||||
|
public void GoToPoint(Vector2 worldPosition)
|
||||||
|
{
|
||||||
|
isManualFollowing = false;
|
||||||
|
if (aiPath != null)
|
||||||
|
{
|
||||||
|
aiPath.enabled = true;
|
||||||
|
aiPath.destination = new Vector3(worldPosition.x, worldPosition.y, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDrawGizmos()
|
||||||
|
{
|
||||||
|
if (debugDrawTarget && Application.isPlaying)
|
||||||
|
{
|
||||||
|
Gizmos.color = Color.cyan;
|
||||||
|
Gizmos.DrawSphere(targetPoint, 0.2f);
|
||||||
|
Gizmos.color = Color.yellow;
|
||||||
|
Gizmos.DrawLine(transform.position, targetPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
--- !u!19 &1
|
--- !u!19 &1
|
||||||
Physics2DSettings:
|
Physics2DSettings:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
serializedVersion: 5
|
serializedVersion: 6
|
||||||
m_Gravity: {x: 0, y: -9.81}
|
m_Gravity: {x: 0, y: -9.81}
|
||||||
m_DefaultMaterial: {fileID: 0}
|
m_DefaultMaterial: {fileID: 0}
|
||||||
m_VelocityIterations: 8
|
m_VelocityIterations: 8
|
||||||
m_PositionIterations: 3
|
m_PositionIterations: 3
|
||||||
m_VelocityThreshold: 1
|
m_BounceThreshold: 1
|
||||||
m_MaxLinearCorrection: 0.2
|
m_MaxLinearCorrection: 0.2
|
||||||
m_MaxAngularCorrection: 8
|
m_MaxAngularCorrection: 8
|
||||||
m_MaxTranslationSpeed: 100
|
m_MaxTranslationSpeed: 100
|
||||||
@@ -19,6 +19,7 @@ Physics2DSettings:
|
|||||||
m_LinearSleepTolerance: 0.01
|
m_LinearSleepTolerance: 0.01
|
||||||
m_AngularSleepTolerance: 2
|
m_AngularSleepTolerance: 2
|
||||||
m_DefaultContactOffset: 0.01
|
m_DefaultContactOffset: 0.01
|
||||||
|
m_ContactThreshold: 0
|
||||||
m_JobOptions:
|
m_JobOptions:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
useMultithreading: 0
|
useMultithreading: 0
|
||||||
@@ -39,18 +40,17 @@ Physics2DSettings:
|
|||||||
m_IslandSolverBodiesPerJob: 50
|
m_IslandSolverBodiesPerJob: 50
|
||||||
m_IslandSolverContactsPerJob: 50
|
m_IslandSolverContactsPerJob: 50
|
||||||
m_SimulationMode: 0
|
m_SimulationMode: 0
|
||||||
|
m_SimulationLayers:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 4294967295
|
||||||
|
m_MaxSubStepCount: 4
|
||||||
|
m_MinSubStepFPS: 30
|
||||||
|
m_UseSubStepping: 0
|
||||||
|
m_UseSubStepContacts: 0
|
||||||
m_QueriesHitTriggers: 1
|
m_QueriesHitTriggers: 1
|
||||||
m_QueriesStartInColliders: 1
|
m_QueriesStartInColliders: 1
|
||||||
m_CallbacksOnDisable: 1
|
m_CallbacksOnDisable: 1
|
||||||
m_ReuseCollisionCallbacks: 1
|
m_ReuseCollisionCallbacks: 1
|
||||||
m_AutoSyncTransforms: 0
|
m_AutoSyncTransforms: 0
|
||||||
m_AlwaysShowColliders: 0
|
m_GizmoOptions: 10
|
||||||
m_ShowColliderSleep: 1
|
m_LayerCollisionMatrix: fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||||
m_ShowColliderContacts: 0
|
|
||||||
m_ShowColliderAABB: 0
|
|
||||||
m_ContactArrowScale: 0.2
|
|
||||||
m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
|
|
||||||
m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
|
|
||||||
m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
|
|
||||||
m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
|
|
||||||
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ TagManager:
|
|||||||
- Water
|
- Water
|
||||||
- UI
|
- UI
|
||||||
- WorldObstacle
|
- WorldObstacle
|
||||||
-
|
- Player
|
||||||
-
|
- Pulver
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
-
|
-
|
||||||
|
|||||||
Reference in New Issue
Block a user