Commit 63276992 authored by 18손재민's avatar 18손재민

Navmesh와 애니메이션 자연스럽게 연결함.

parent 09ca015c
using UnityEngine;
namespace UnityStandardAssets.Characters.ThirdPerson
{
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Animator))]
public class ThirdPersonAnim : MonoBehaviour
{
[SerializeField] float m_MovingTurnSpeed = 360;
[SerializeField] float m_StationaryTurnSpeed = 180;
[SerializeField] float m_JumpPower = 6f;
[Range(1f, 4f)] [SerializeField] float m_GravityMultiplier = 2f;
[SerializeField] float m_RunCycleLegOffset = 0.2f; //specific to the character in sample assets, will need to be modified to work with others
[SerializeField] float m_MoveSpeedMultiplier = 1f;
[SerializeField] float m_AnimSpeedMultiplier = 1f;
[SerializeField] float m_GroundCheckDistance = 0.2f;
Rigidbody m_Rigidbody;
//Animator m_Animator;
bool m_IsGrounded;
float m_OrigGroundCheckDistance;
const float k_Half = 0.5f;
float m_TurnAmount;
float m_ForwardAmount;
Vector3 m_GroundNormal;
float m_CapsuleHeight;
Vector3 m_CapsuleCenter;
CapsuleCollider m_Capsule;
bool m_Crouching;
void Start()
{
//m_Animator = GetComponent<Animator>();
m_Rigidbody = GetComponent<Rigidbody>();
m_Capsule = GetComponent<CapsuleCollider>();
m_CapsuleHeight = m_Capsule.height;
m_CapsuleCenter = m_Capsule.center;
m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
m_OrigGroundCheckDistance = m_GroundCheckDistance;
}
public void Move(Vector3 move, bool crouch, bool jump)
{
// convert the world relative moveInput vector into a local-relative
// turn amount and forward amount required to head in the desired
// direction.
if (move.magnitude > 1f) move.Normalize();
move = transform.InverseTransformDirection(move);
//CheckGroundStatus();
move = Vector3.ProjectOnPlane(move, m_GroundNormal);
m_TurnAmount = Mathf.Atan2(move.x, move.z);
m_ForwardAmount = move.z;
ApplyExtraTurnRotation();
// control and velocity handling is different when grounded and airborne:
if (m_IsGrounded)
{
//HandleGroundedMovement(crouch, jump);
}
else
{
HandleAirborneMovement();
}
ScaleCapsuleForCrouching(crouch);
PreventStandingInLowHeadroom();
// send input and other state parameters to the animator
//UpdateAnimator(move);
}
void ScaleCapsuleForCrouching(bool crouch)
{
if (m_IsGrounded && crouch)
{
if (m_Crouching) return;
m_Capsule.height = m_Capsule.height / 2f;
m_Capsule.center = m_Capsule.center / 2f;
m_Crouching = true;
}
else
{
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
{
m_Crouching = true;
return;
}
m_Capsule.height = m_CapsuleHeight;
m_Capsule.center = m_CapsuleCenter;
m_Crouching = false;
}
}
void PreventStandingInLowHeadroom()
{
// prevent standing up in crouch-only zones
if (!m_Crouching)
{
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
{
m_Crouching = true;
}
}
}
/*void UpdateAnimator(Vector3 move)
{
// update the animator parameters
m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
m_Animator.SetBool("Crouch", m_Crouching);
m_Animator.SetBool("OnGround", m_IsGrounded);
if (!m_IsGrounded)
{
m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
}
// calculate which leg is behind, so as to leave that leg trailing in the jump animation
// (This code is reliant on the specific run cycle offset in our animations,
// and assumes one leg passes the other at the normalized clip times of 0.0 and 0.5)
float runCycle =
Mathf.Repeat(
m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
if (m_IsGrounded)
{
m_Animator.SetFloat("JumpLeg", jumpLeg);
}
// the anim speed multiplier allows the overall speed of walking/running to be tweaked in the inspector,
// which affects the movement speed because of the root motion.
if (m_IsGrounded && move.magnitude > 0)
{
m_Animator.speed = m_AnimSpeedMultiplier;
}
else
{
// don't use that while airborne
m_Animator.speed = 1;
}
}*/
void HandleAirborneMovement()
{
// apply extra gravity from multiplier:
Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.gravity;
m_Rigidbody.AddForce(extraGravityForce);
m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0.01f;
}
/*
void HandleGroundedMovement(bool crouch, bool jump)
{
// check whether conditions are right to allow a jump:
if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
{
// jump!
m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z);
m_IsGrounded = false;
m_Animator.applyRootMotion = false;
m_GroundCheckDistance = 0.1f;
}
}*/
void ApplyExtraTurnRotation()
{
// help the character turn faster (this is in addition to root rotation in the animation)
float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
}
/*
public void OnAnimatorMove()
{
// we implement this function to override the default root motion.
// this allows us to modify the positional speed before it's applied.
if (m_IsGrounded && Time.deltaTime > 0)
{
Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaTime;
// we preserve the existing y part of the current velocity.
v.y = m_Rigidbody.velocity.y;
m_Rigidbody.velocity = v;
}
}
void CheckGroundStatus()
{
RaycastHit hitInfo;
#if UNITY_EDITOR
// helper to visualise the ground check ray in the scene view
Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
#endif
// 0.1f is a small offset to start the ray from inside the character
// it is also good to note that the transform position in the sample assets is at the base of the character
if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
{
m_GroundNormal = hitInfo.normal;
m_IsGrounded = true;
m_Animator.applyRootMotion = true;
}
else
{
m_IsGrounded = false;
m_GroundNormal = Vector3.up;
m_Animator.applyRootMotion = false;
}
}*/
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: e7eb2fe133fb4eb45bffdded306b23f4
NativeFormatImporter:
guid: 50754cea15c27674599737e6710b47f6
MonoImporter:
externalObjects: {}
mainObjectFileID: 23800000
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -1324,6 +1324,8 @@ GameObject:
- component: {fileID: 103473560334342872}
- component: {fileID: 9050027863979790995}
- component: {fileID: 6489731509539496108}
- component: {fileID: 8675505305325970040}
- component: {fileID: 871027520175336362}
m_Layer: 0
m_Name: jackson
m_TagString: Player
......@@ -1359,7 +1361,7 @@ Animator:
m_GameObject: {fileID: 494213313239918027}
m_Enabled: 1
m_Avatar: {fileID: 9000000, guid: 21bb8ae9866c4304198832331df496dc, type: 3}
m_Controller: {fileID: 0}
m_Controller: {fileID: 9100000, guid: eaf238dc35bc3074fa2fffcbcbbe58df, type: 2}
m_CullingMode: 1
m_UpdateMode: 0
m_ApplyRootMotion: 0
......@@ -1377,8 +1379,8 @@ NavMeshAgent:
m_GameObject: {fileID: 494213313239918027}
m_Enabled: 0
m_AgentTypeID: 0
m_Radius: 0.5
m_Speed: 3.5
m_Radius: 0.3
m_Speed: 1
m_Acceleration: 8
avoidancePriority: 50
m_AngularSpeed: 1000
......@@ -1399,12 +1401,12 @@ NavMeshObstacle:
m_GameObject: {fileID: 494213313239918027}
m_Enabled: 1
serializedVersion: 3
m_Shape: 1
m_Extents: {x: 0.5, y: 1, z: 0.5}
m_Shape: 0
m_Extents: {x: 0.3, y: 1, z: 0.3}
m_MoveThreshold: 0.1
m_Carve: 0
m_Carve: 1
m_CarveOnlyStationary: 1
m_Center: {x: 0, y: 1.115, z: 0}
m_Center: {x: 0, y: 1.12, z: 0}
m_TimeToStationary: 0.5
--- !u!136 &9050027863979790995
CapsuleCollider:
......@@ -1433,6 +1435,42 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
head: {fileID: 3233955354714130270}
--- !u!114 &8675505305325970040
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 494213313239918027}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 50754cea15c27674599737e6710b47f6, type: 3}
m_Name:
m_EditorClassIdentifier:
m_MovingTurnSpeed: 360
m_StationaryTurnSpeed: 180
m_JumpPower: 6
m_GravityMultiplier: 2
m_RunCycleLegOffset: 0.2
m_MoveSpeedMultiplier: 1
m_AnimSpeedMultiplier: 1
m_GroundCheckDistance: 0.2
--- !u!54 &871027520175336362
Rigidbody:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 494213313239918027}
serializedVersion: 2
m_Mass: 1
m_Drag: 0
m_AngularDrag: 0.05
m_UseGravity: 0
m_IsKinematic: 0
m_Interpolate: 0
m_Constraints: 0
m_CollisionDetection: 0
--- !u!1 &494213313239918029
GameObject:
m_ObjectHideFlags: 0
......
......@@ -674,8 +674,7 @@ PrefabInstance:
type: 3}
propertyPath: m_NavMeshData
value:
objectReference: {fileID: 23800000, guid: e7eb2fe133fb4eb45bffdded306b23f4,
type: 2}
objectReference: {fileID: 0}
- target: {fileID: 7277015661519863742, guid: 20dee07e28273f049a9093ae4453912f,
type: 3}
propertyPath: m_LocalPosition.x
......
......@@ -7,6 +7,7 @@ public class CameraController : MonoBehaviour
Vector3 dragOrigin;
public float dragSpeed;
Vector3 previousPos;
Vector3 previousAngle;
float shootingFov = 60f;
float mapFov = 40f;
......@@ -54,9 +55,10 @@ public class CameraController : MonoBehaviour
{
float startTime = Time.time;
Vector3 posDiff = (player.head.transform.position - transform.position) / 40;
Vector3 angleDiff = (new Vector3(0, transform.eulerAngles.y, 0) - transform.eulerAngles) / 40;
Vector3 angleDiff = (player.head.transform.eulerAngles - transform.eulerAngles) / 40;
float fovDiff = (shootingFov - mapFov) / 40f;
previousPos = transform.position;
previousAngle = transform.eulerAngles;
for (int i = 0; i < 40; i++)
{
yield return null;
......@@ -74,7 +76,7 @@ public class CameraController : MonoBehaviour
{
float startTime = Time.time;
Vector3 posDiff = (previousPos - transform.position) / 40;
Vector3 angleDiff = (new Vector3(30, transform.eulerAngles.y, transform.eulerAngles.z) - transform.eulerAngles) / 40;
Vector3 angleDiff = (previousAngle - transform.eulerAngles) / 40;
float fovDiff = (mapFov - shootingFov) / 40f;
for (int i = 0; i < 40; i++)
{
......
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityStandardAssets.Characters.ThirdPerson;
public class Player : MonoBehaviour
{
......@@ -12,17 +13,22 @@ public class Player : MonoBehaviour
Coroutine playerArrivalCheck;
public GameObject head;
Animator anim;
NavMeshAgent agent;
ThirdPersonAnim character;
public IEnumerator SetCurrentPlayer()
{
GetComponent<NavMeshObstacle>().enabled = false;
yield return null;
GetComponent<NavMeshAgent>().enabled = true;
StartCoroutine(MapManager.inst.Rebaker());
}
public void ResetCurrentPlayer()
{
GetComponent<NavMeshAgent>().enabled = false;
GetComponent<NavMeshObstacle>().enabled = true;
StartCoroutine(MapManager.inst.Rebaker());
PlayerController.inst.currentPlayer = null;
}
/// <summary>
......@@ -35,13 +41,17 @@ public class Player : MonoBehaviour
NavMeshPath path = new NavMeshPath();
if(playerArrivalCheck != null)
StopCoroutine(playerArrivalCheck);
PlayerController.inst.isPlayerMoving = true;
playerArrivalCheck = StartCoroutine(CheckIfPlayerArrived(destination));
agent.CalculatePath(destination, path);
if(path.status == NavMeshPathStatus.PathComplete)
{
PlayerController.inst.isPlayerMoving = true;
playerArrivalCheck = StartCoroutine(CheckIfPlayerArrived(destination));
GetComponent<NavMeshAgent>().SetDestination(destination);
}
else
{
Debug.Log("Destination is not reachable.");
}
}
/// <summary>
/// Check if player is arrived at the destination.
......@@ -49,12 +59,14 @@ public class Player : MonoBehaviour
/// <param name="destination">Destination of the player.</param>
/// <returns></returns>
IEnumerator CheckIfPlayerArrived(Vector3 destination)
{
while (Mathf.Abs(transform.position.x - destination.x) > 0.01f || Mathf.Abs(transform.position.z - destination.z) > 0.01f)
{
anim.SetBool("isWalking", true);
while (Mathf.Abs(transform.position.x - destination.x) > 0.01f || Mathf.Abs(transform.position.z - destination.z) > 0.01f)
{
yield return null;
}
transform.position = new Vector3(destination.x, transform.position.y, destination.z);
}
transform.position = new Vector3(destination.x, transform.position.y, destination.z);
anim.SetBool("isWalking", false);
PlayerController.inst.isPlayerMoving = false;
}
public IEnumerator CountPlayerClick(float startTime)
......@@ -77,12 +89,21 @@ public class Player : MonoBehaviour
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
agent = GetComponent<NavMeshAgent>();
character = GetComponent<ThirdPersonAnim>();
agent.updateRotation = false;
}
// Update is called once per frame
void Update()
{
}
private void LateUpdate()
{
if(agent.isActiveAndEnabled && agent.velocity.magnitude > 0)
transform.rotation = Quaternion.LookRotation(agent.velocity.normalized);
}
}
......@@ -73,7 +73,7 @@ NavMeshProjectSettings:
m_Settings:
- serializedVersion: 2
agentTypeID: 0
agentRadius: 0.3
agentRadius: 0.2
agentHeight: 2
agentSlope: 45
agentClimb: 0.75
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment