Attach Camera to Player
This commit is contained in:
@@ -20,6 +20,16 @@ public class CharacterMovement : NetworkBehaviour
|
||||
bool lastSentWalking;
|
||||
bool lastSentRunning;
|
||||
|
||||
// assign this in the player prefab to an empty child transform positioned where the camera should sit (e.g. head)
|
||||
public Transform cameraMount;
|
||||
|
||||
// camera follow settings
|
||||
Camera mainCamera;
|
||||
Vector3 cameraLocalOffsetStable = new Vector3(0f, 2f, -4f); // fallback offset (local)
|
||||
public float followSpeed = 5f;
|
||||
public float idleFollowSpeed = 0.5f; // slower smoothing while idle (keeps camera stable)
|
||||
public Vector3 cameraLookOffset = new Vector3(0f, 1.5f, 0f); // where camera looks relative to player root
|
||||
|
||||
void Awake()
|
||||
{
|
||||
input = new PlayerInput();
|
||||
@@ -56,6 +66,32 @@ public class CharacterMovement : NetworkBehaviour
|
||||
HandleRotation();
|
||||
}
|
||||
|
||||
// Camera follow should be in LateUpdate so it follows the final character pose for the frame
|
||||
void LateUpdate()
|
||||
{
|
||||
if (!isLocalPlayer) return;
|
||||
if (mainCamera == null) return;
|
||||
|
||||
// Desired world position based on the stable local offset (relative to player root)
|
||||
Vector3 desiredWorld = transform.TransformPoint(cameraLocalOffsetStable);
|
||||
|
||||
if (movementPressed)
|
||||
{
|
||||
// while moving: follow the player (smooth)
|
||||
mainCamera.transform.position = Vector3.Lerp(mainCamera.transform.position, desiredWorld, Time.deltaTime * followSpeed);
|
||||
}
|
||||
else
|
||||
{
|
||||
// while idle: keep camera stable behind the player (don't follow micro animation bobbing)
|
||||
// Update only XZ to remain behind, preserve camera's current Y (height) to avoid vertical bob
|
||||
Vector3 idleTarget = new Vector3(desiredWorld.x, mainCamera.transform.position.y, desiredWorld.z);
|
||||
mainCamera.transform.position = Vector3.Lerp(mainCamera.transform.position, idleTarget, Time.deltaTime * idleFollowSpeed);
|
||||
}
|
||||
|
||||
// Always look at the player (with an offset so we look near the torso/head)
|
||||
mainCamera.transform.LookAt(transform.position + cameraLookOffset);
|
||||
}
|
||||
|
||||
void HandleRotation()
|
||||
{
|
||||
Vector3 currentPosition = transform.position;
|
||||
@@ -142,11 +178,46 @@ public class CharacterMovement : NetworkBehaviour
|
||||
{
|
||||
Debug.Log("Local player started: " + netId);
|
||||
input.CharacterControls.Enable();
|
||||
|
||||
// Setup camera for local player (do not parent to animated mount to avoid animation bobbing)
|
||||
mainCamera = Camera.main;
|
||||
if (mainCamera == null)
|
||||
{
|
||||
Debug.LogWarning("No Camera.main found in scene to attach to player.");
|
||||
return;
|
||||
}
|
||||
|
||||
// compute a stable local offset based on cameraMount, but use player root as the reference so animated child motion is ignored
|
||||
if (cameraMount != null)
|
||||
{
|
||||
cameraLocalOffsetStable = transform.InverseTransformPoint(cameraMount.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
// fallback to a sensible offset if no mount assigned
|
||||
cameraLocalOffsetStable = new Vector3(0f, 2f, -4f);
|
||||
Debug.LogWarning("cameraMount not assigned on player prefab. Using fallback offset.");
|
||||
}
|
||||
|
||||
// unparent camera so we control world position directly
|
||||
mainCamera.transform.SetParent(null, true);
|
||||
|
||||
// ensure only the local player's camera has an active AudioListener
|
||||
var audio = mainCamera.GetComponent<AudioListener>();
|
||||
if (audio != null) audio.enabled = true;
|
||||
}
|
||||
|
||||
public override void OnStopLocalPlayer()
|
||||
{
|
||||
input.CharacterControls.Disable();
|
||||
|
||||
// optionally disable audio listener to avoid duplicates
|
||||
if (mainCamera != null)
|
||||
{
|
||||
var audio = mainCamera.GetComponent<AudioListener>();
|
||||
if (audio != null) audio.enabled = false;
|
||||
}
|
||||
mainCamera = null;
|
||||
}
|
||||
|
||||
// Called on the server when client issues the command
|
||||
|
||||
Reference in New Issue
Block a user