Adventure Creator Wikia
(Created page with "This script allows for integration with Unity's own Third Person Controller, which is included in their own Standard Assets package.  It can be used to move a character with ...")
 
Tag: Visual edit
 
(9 intermediate revisions by 2 users not shown)
Line 1: Line 1:
This script allows for integration with Unity's own Third Person Controller, which is included in their own Standard Assets package.  It can be used to move a character with both Direct and Point And Click methods, using the Third Person Controller script.
+
This script allows for integration with Unity's own Third Person Controller, which is included in their own [https://assetstore.unity.com/packages/essentials/asset-packs/standard-assets-32351 Standard Assets package].  It can be used to move a character with both Direct and Point And Click methods, using the Third Person Controller script.
   
 
To use it:
 
To use it:
#Take the existing ThirdPersonController or AIThirdPersonController prefab, and remove any existing control script (with ThirdPersonController, this is ThirdPersonUserControl; with AIThirdPersonController, this is AICharacterControl).
+
#Take the existing '''ThirdPersonController''' or '''AIThirdPersonController''' prefab, and remove any existing control script (with '''ThirdPersonController''', this is '''ThirdPersonUserControl'''; with '''AIThirdPersonController''', this is '''AICharacterControl''').
 
#Attach either AC's Player or NPC component
 
#Attach either AC's Player or NPC component
  +
#In AC's Settings Manager, set your game's '''Movement method''' to either '''Point And Click''' or '''Direct'''
#Attach the script below
 
  +
#Attach the script below to the character's root object
#(Optional) To allow for AC-controlled movement during e.g. cutscenes, also attach and configure a NavMeshAgent.  The scene must also rely on Unity Navigation pathfinding, as covered in the AC Manual.
 
  +
#''(Optional)'' To allow for AC-controlled movement during e.g. cutscenes, also attach and configure a NavMeshAgent.  The scene must also rely on '''Unity Navigation''' pathfinding, as covered in the AC Manual.<br>
   
  +
UnityThirdPersonIntegration.cs:<syntaxhighlight lang="csharp">
  +
using System.Collections;
  +
using System.Collections.Generic;
  +
using UnityEngine;
  +
using UnityEngine.AI;
  +
using UnityStandardAssets.Characters.ThirdPerson;
  +
using AC;
   
  +
public class UnityThirdPersonIntegration : MonoBehaviour
  +
{
   
  +
private NavMeshAgent navMeshAgent;
UnityThirdPersonIntegration.cs:
 
  +
private AC.Char characterAC;
<span style="font-weight:700;color:#ad7fa7;">using</span><span style="color:#d3d7ce;"> System</span><span style="color:#d3d7ce;">.</span><span style="color:#d3d7ce;">Collections</span><span style="color:#d3d7ce;">;</span>
 
  +
private AC.Paths characterPaths;
<span style="font-weight:700;color:#ad7fa7;">using</span><span style="color:#d3d7ce;"> System</span><span style="color:#d3d7ce;">.</span><span style="color:#d3d7ce;">Collections</span><span style="color:#d3d7ce;">.</span><span style="color:#d3d7ce;">Generic</span><span style="color:#d3d7ce;">;</span>
 
  +
private ThirdPersonCharacter characterTP;
<span style="font-weight:700;color:#ad7fa7;">using</span><span style="color:#d3d7ce;"> UnityEngine</span><span style="color:#d3d7ce;">;</span>
 
  +
private enum ControlState { UnderDirectControl, UnityPathfinding, ACTurning };
<span style="font-weight:700;color:#ad7fa7;">using</span><span style="color:#d3d7ce;"> UnityEngine</span><span style="color:#d3d7ce;">.</span><span style="color:#d3d7ce;">AI</span><span style="color:#d3d7ce;">;</span>
 
  +
private ControlState controlState = ControlState.ACTurning;
<span style="font-weight:700;color:#ad7fa7;">using</span><span style="color:#d3d7ce;"> UnityStandardAssets</span><span style="color:#d3d7ce;">.</span><span style="color:#d3d7ce;">Characters</span><span style="color:#d3d7ce;">.</span><span style="color:#d3d7ce;">ThirdPerson</span><span style="color:#d3d7ce;">;</span>
 
  +
private Vector3 m_CamForward;
<span style="font-weight:700;color:#ad7fa7;">using</span><span style="color:#d3d7ce;"> AC</span><span style="color:#d3d7ce;">;</span>
 
  +
private Vector3 m_Move;
 
  +
private bool m_Jump;
<span style="font-weight:700;color:#ad7fa7;">public</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">class</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">UnityThirdPersonIntegration</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">:</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">MonoBehaviour</span>
 
  +
private float m_moveMultiplier = 0.5f;
<span style="color:#d3d7ce;">{</span>
 
  +
private Camera m_mainCamera;
 
  +
private Vector3 agentPosition = Vector3.zero;
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">NavMeshAgent</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">;</span>
 
  +
private MotionControl originalMotionControl;
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> AC</span><span style="color:#d3d7ce;">.</span><span style="color:#8ae233;">Char</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">characterAC</span><span style="color:#d3d7ce;">;</span>
 
  +
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ThirdPersonCharacter</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">characterTP</span><span style="color:#d3d7ce;">;</span>
 
  +
private void Awake()
 
  +
{
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">enum</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">{</span><span style="color:#d3d7ce;"> UnderDirectControl</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> UnityPathfinding</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> ACTurning </span><span style="color:#d3d7ce;">}</span><span style="color:#d3d7ce;">;</span>
 
  +
m_mainCamera = KickStarter.CameraMain;
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">controlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">ACTurning</span><span style="color:#d3d7ce;">;</span>
 
  +
navMeshAgent = GetComponent<NavMeshAgent>();
 
  +
if (navMeshAgent != null)
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">m_CamForward</span><span style="color:#d3d7ce;">;</span>
 
  +
{
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">m_Move</span><span style="color:#d3d7ce;">;</span>
 
  +
navMeshAgent.updateRotation = false;
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">bool</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">m_Jump</span><span style="color:#d3d7ce;">;</span>
 
  +
navMeshAgent.updatePosition = false;
 
  +
}
 
  +
characterAC = GetComponent<Char>();
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">void</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">Start</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span>
 
  +
originalMotionControl = characterAC.motionControl;
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">{</span>
 
  +
characterAC.motionControl = MotionControl.JustTurning;
<span style="color:#d3d7ce;">        </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Get</span><span style="color:#888a85;"> </span><span style="color:#888a85;">component</span><span style="color:#888a85;"> </span><span style="color:#888a85;">variables</span><span style="color:#888a85;">,</span><span style="color:#888a85;"> </span><span style="color:#888a85;">init</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">NavMeshAgent</span><span style="color:#888a85;">,</span><span style="color:#888a85;"> </span><span style="color:#888a85;">and</span><span style="color:#888a85;"> </span><span style="color:#888a85;">force</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Manual</span><span style="color:#888a85;"> </span><span style="color:#888a85;">motion</span><span style="color:#888a85;"> </span><span style="color:#888a85;">control</span><span style="color:#888a85;"> </span><span style="color:#888a85;">to</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">AC</span><span style="color:#888a85;"> character</span>
 
  +
characterPaths = GetComponent<Paths>();
 
  +
characterTP = GetComponent<ThirdPersonCharacter>();
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">GetComponentInChildren</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;"><</span><span style="color:#8ae233;">NavMeshAgent</span><span style="color:#d3d7ce;">>()</span><span style="color:#d3d7ce;">;</span>
 
  +
}
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">updateRotation</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">;</span>
 
  +
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">updatePosition</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">true</span><span style="color:#d3d7ce;">;</span>
 
  +
private void OnEnable ()
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">characterAC</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">GetComponent</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;"><</span><span style="color:#8ae233;">Char</span><span style="color:#d3d7ce;">>()</span><span style="color:#d3d7ce;">;</span>
 
  +
characterAC = GetComponent<Char>();
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">characterAC</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">motionControl</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">MotionControl</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">JustTurning</span><span style="color:#d3d7ce;">;</span>
 
  +
originalMotionControl = characterAC.motionControl;
 
  +
characterAC.motionControl = MotionControl.JustTurning;
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">characterTP</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">GetComponent</span><span style="color:#d3d7ce;"><</span><span style="color:#8ae233;">ThirdPersonCharacter</span><span style="color:#d3d7ce;">>()</span><span style="color:#d3d7ce;">;</span>
 
  +
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">}</span>
 
  +
EventManager.OnCharacterSetPath += SetCharacterPath;
 
+
}
  +
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">void</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">Update</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span>
 
  +
private void OnDisable ()
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">{</span>
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Update</span><span style="color:#888a85;"> </span><span style="color:#888a85;">what</span><span style="color:#888a85;"> </span><span style="color:#888a85;">our</span><span style="color:#888a85;"> </span><span style="color:#888a85;">current</span><span style="color:#888a85;"> </span><span style="color:#888a85;">control</span><span style="color:#888a85;"> </span><span style="color:#888a85;">state</span><span style="color:#888a85;"> is</span>
 
  +
characterAC.motionControl = originalMotionControl;
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">UpdateControlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span><span style="color:#d3d7ce;">;</span>
 
  +
EventManager.OnCharacterSetPath -= SetCharacterPath;
 
  +
}
<span style="color:#d3d7ce;">        </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Move</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">character</span><span style="color:#888a85;"> </span><span style="color:#888a85;">according</span><span style="color:#888a85;"> </span><span style="color:#888a85;">to</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">current</span><span style="color:#888a85;"> </span><span style="color:#888a85;">control</span><span style="color:#888a85;"> state</span>
 
  +
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">UpdateMovement</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span><span style="color:#d3d7ce;">;</span>
 
  +
private void Update()
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">}</span>
 
+
{
  +
UpdateControlState();
 
  +
UpdateMovement();
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">void</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">FixedUpdate</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span>
 
  +
}
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">{</span>
 
  +
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">controlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">==</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">UnderDirectControl</span><span style="color:#d3d7ce;">)</span>
 
  +
private void FixedUpdate()
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
{
<span style="color:#d3d7ce;">            </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Do</span><span style="color:#888a85;"> </span><span style="color:#888a85;">all</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">input</span><span style="color:#888a85;"> </span><span style="color:#888a85;">checks</span><span style="color:#888a85;"> </span><span style="color:#888a85;">for</span><span style="color:#888a85;"> </span><span style="color:#888a85;">direct</span><span style="color:#888a85;"> input</span>
 
  +
if (controlState == ControlState.UnderDirectControl)
<span style="color:#d3d7ce;">            </span><span style="font-style:italic;color:#d3d7ce;">UpdateDirectInput</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span><span style="color:#d3d7ce;">;</span><span style="color:#d3d7ce;">    </span>
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
// Do all the input checks for direct input
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">}</span>
 
  +
UpdateDirectInput();
 
  +
}
 
  +
}
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">void</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">UpdateControlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span>
 
  +
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">{</span>
 
  +
private void UpdateControlState()
<span style="color:#d3d7ce;">        </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Check</span><span style="color:#888a85;"> </span><span style="color:#888a85;">if</span><span style="color:#888a85;"> </span><span style="color:#888a85;">we</span><span style="color:#888a85;"> </span><span style="color:#888a85;">want</span><span style="color:#888a85;"> </span><span style="color:#888a85;">to</span><span style="color:#888a85;"> </span><span style="color:#888a85;">determine</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">character</span><span style="color:#888a85;">'</span><span style="color:#888a85;">s</span><span style="color:#888a85;"> </span><span style="color:#888a85;">position</span><span style="color:#888a85;"> </span><span style="color:#888a85;">through</span><span style="color:#888a85;"> </span><span style="color:#888a85;">AC</span><span style="color:#888a85;">,</span><span style="color:#888a85;"> </span><span style="color:#888a85;">or</span><span style="color:#888a85;"> </span><span style="color:#888a85;">just</span><span style="color:#888a85;"> </span><span style="color:#888a85;">through</span><span style="color:#888a85;"> </span><span style="color:#888a85;">direct</span><span style="color:#888a85;"> input</span>
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#d3d7ce;">!</span><span style="color:#8ae233;">KickStarter</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">stateHandler</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">IsInGameplay</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span><span style="color:#d3d7ce;"> || </span><span style="color:#8ae233;">KickStarter</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">settingsManager</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">movementMethod</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">==</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">MovementMethod</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">PointAndClick</span><span style="color:#d3d7ce;">)</span>
 
  +
if (!KickStarter.stateHandler.IsInGameplay() || !characterAC.IsPlayer || characterAC.IsMovingAlongPath() || KickStarter.settingsManager.movementMethod == MovementMethod.PointAndClick)
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
{
<span style="color:#d3d7ce;">            </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Check</span><span style="color:#888a85;"> </span><span style="color:#888a85;">if</span><span style="color:#888a85;"> </span><span style="color:#888a85;">we</span><span style="color:#888a85;"> </span><span style="color:#888a85;">want</span><span style="color:#888a85;"> </span><span style="color:#888a85;">to</span><span style="color:#888a85;"> </span><span style="color:#888a85;">make</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">character</span><span style="color:#888a85;"> </span><span style="color:#888a85;">pathfind</span><span style="color:#888a85;">,</span><span style="color:#888a85;"> </span><span style="color:#888a85;">or</span><span style="color:#888a85;"> </span><span style="color:#888a85;">do</span><span style="color:#888a85;"> </span><span style="color:#888a85;">nothing</span><span style="color:#888a85;"> </span><span style="color:#888a85;">while</span><span style="color:#888a85;"> </span><span style="color:#888a85;">AC</span><span style="color:#888a85;"> </span><span style="color:#888a85;">turns</span><span style="color:#888a85;"> them</span>
 
  +
if (characterAC.charState == CharState.Move)
<span style="color:#d3d7ce;">            </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">characterAC</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">charState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">==</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">CharState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">Move</span><span style="color:#d3d7ce;">)</span>
 
  +
{
<span style="color:#d3d7ce;">            </span><span style="color:#d3d7ce;">{</span>
 
  +
controlState = ControlState.UnityPathfinding;
<span style="color:#d3d7ce;">                </span><span style="font-style:italic;color:#d3d7ce;">controlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">UnityPathfinding</span><span style="color:#d3d7ce;">;</span>
 
  +
}
<span style="color:#d3d7ce;">            </span><span style="color:#d3d7ce;">}</span>
 
  +
else
<span style="color:#d3d7ce;">            </span><span style="font-weight:700;color:#ffffff;">else</span>
 
  +
{
<span style="color:#d3d7ce;">            </span><span style="color:#d3d7ce;">{</span>
 
  +
controlState = ControlState.ACTurning;
<span style="color:#d3d7ce;">                </span><span style="font-style:italic;color:#d3d7ce;">controlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">ACTurning</span><span style="color:#d3d7ce;">;</span>
 
  +
}
<span style="color:#d3d7ce;">            </span><span style="color:#d3d7ce;">}</span>
 
  +
}
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
else
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">else</span>
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
controlState = ControlState.UnderDirectControl;
<span style="color:#d3d7ce;">            </span><span style="font-style:italic;color:#d3d7ce;">controlState</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">UnderDirectControl</span><span style="color:#d3d7ce;">;</span>
 
  +
}
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
}
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">}</span>
 
  +
 
  +
private void UpdateMovement()
 
  +
{
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">void</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">UpdateMovement</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span>
 
  +
switch (controlState)
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">{</span>
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">switch</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">controlState</span><span style="color:#d3d7ce;">)</span>
 
  +
case ControlState.UnderDirectControl:
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
if (navMeshAgent != null)
<span style="color:#d3d7ce;">            </span><span style="font-weight:700;color:#ffffff;">case</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">UnderDirectControl</span><span style="color:#d3d7ce;">:</span>
 
  +
{
<span style="color:#d3d7ce;">                </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">enabled</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">;</span>
 
  +
navMeshAgent.enabled = false;
<span style="color:#d3d7ce;">                </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#d3d7ce;">!</span><span style="font-style:italic;color:#d3d7ce;">m_Jump</span><span style="color:#d3d7ce;">)</span>
 
  +
}
<span style="color:#d3d7ce;">                </span><span style="color:#d3d7ce;">{</span>
 
  +
else
<span style="color:#d3d7ce;">                    </span><span style="font-style:italic;color:#d3d7ce;">m_Jump</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Input</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">GetButtonDown</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#edd400;">"</span><span style="color:#edd400;">Jump</span><span style="color:#edd400;">"</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
{
<span style="color:#d3d7ce;">                </span><span style="color:#d3d7ce;">}</span>
 
  +
ACDebug.LogWarning("A NavMeshAgent component is required on " + gameObject.name, this);
<span style="color:#d3d7ce;">                </span><span style="font-weight:700;color:#ad7fa7;">break</span><span style="color:#d3d7ce;">;</span>
 
  +
}
 
  +
if (!m_Jump)
<span style="color:#d3d7ce;">            </span><span style="font-weight:700;color:#ffffff;">case</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">UnityPathfinding</span><span style="color:#d3d7ce;">:</span>
 
  +
{
<span style="color:#d3d7ce;">                </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;"> !</span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">null</span><span style="color:#d3d7ce;">)</span>
 
  +
m_Jump = Input.GetButtonDown("Jump");
<span style="color:#d3d7ce;">                </span><span style="color:#d3d7ce;">{</span>
 
  +
}
<span style="color:#d3d7ce;">                    </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">enabled</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">true</span><span style="color:#d3d7ce;">;</span>
 
  +
break;
<span style="color:#d3d7ce;">                    </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">isOnNavMesh</span><span style="color:#d3d7ce;">)</span>
 
  +
<span style="color:#d3d7ce;">                    </span><span style="color:#d3d7ce;">{</span>
 
  +
case ControlState.UnityPathfinding:
<span style="color:#d3d7ce;">                        </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">SetDestination</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">characterAC</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">GetTargetPosition</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-weight:700;color:#ce5c00;">true</span><span style="color:#d3d7ce;">))</span><span style="color:#d3d7ce;">;</span>
 
  +
if (navMeshAgent != null)
 
  +
{
<span style="color:#d3d7ce;">                        </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">remainingDistance</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">></span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">stoppingDistance</span><span style="color:#d3d7ce;">)</span>
 
  +
navMeshAgent.enabled = true;
<span style="color:#d3d7ce;">                        </span><span style="color:#d3d7ce;">{</span>
 
  +
}
<span style="color:#d3d7ce;">                            </span><span style="font-style:italic;color:#d3d7ce;">characterTP</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">Move</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">desiredVelocity</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
if (navMeshAgent != null && navMeshAgent.isOnNavMesh)
<span style="color:#d3d7ce;">                        </span><span style="color:#d3d7ce;">}</span>
 
  +
{
<span style="color:#d3d7ce;">                        </span><span style="font-weight:700;color:#ffffff;">else</span>
 
  +
if (navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance)
<span style="color:#d3d7ce;">                        </span><span style="color:#d3d7ce;">{</span>
 
  +
{
<span style="color:#d3d7ce;">                            </span><span style="font-style:italic;color:#d3d7ce;">characterTP</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">Move</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">zero</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
if (characterAC.isRunning)
<span style="color:#d3d7ce;">                        </span><span style="color:#d3d7ce;">}</span>
 
  +
{
<span style="color:#d3d7ce;">                    </span><span style="color:#d3d7ce;">}</span>
 
  +
m_moveMultiplier = 1.0f;
<span style="color:#d3d7ce;">                </span><span style="color:#d3d7ce;">}</span>
 
  +
}
<span style="color:#d3d7ce;">                </span><span style="font-weight:700;color:#ad7fa7;">break</span><span style="color:#d3d7ce;">;</span>
 
  +
else
 
  +
{
<span style="color:#d3d7ce;">            </span><span style="font-weight:700;color:#ffffff;">case</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">ControlState</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">ACTurning</span><span style="color:#d3d7ce;">:</span>
 
  +
m_moveMultiplier = 0.5f;
<span style="color:#d3d7ce;">                </span><span style="font-style:italic;color:#d3d7ce;">characterTP</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">Move</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">zero</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
}
<span style="color:#d3d7ce;">                </span><span style="font-weight:700;color:#ad7fa7;">break</span><span style="color:#d3d7ce;">;</span>
 
  +
characterTP.Move(navMeshAgent.desiredVelocity * m_moveMultiplier, false, false);
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
}
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">}</span>
 
  +
else
 
  +
{
 
  +
characterTP.Move(Vector3.zero, false, false);
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">void</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">UpdateDirectInput</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span>
 
  +
}
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">{</span>
 
  +
}
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ad7fa7;">float</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">h</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Input</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">GetAxis</span><span style="color:#d3d7ce;">(</span><span style="color:#edd400;">"</span><span style="color:#edd400;">Horizontal</span><span style="color:#edd400;">"</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
else
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ad7fa7;">float</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">v</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Input</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">GetAxis</span><span style="color:#d3d7ce;">(</span><span style="color:#edd400;">"</span><span style="color:#edd400;">Vertical</span><span style="color:#edd400;">"</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ad7fa7;">bool</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">crouch</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Input</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">GetKey</span><span style="color:#d3d7ce;">(</span><span style="color:#8ae233;">KeyCode</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">C</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
characterAC.Teleport(characterAC.GetTargetPosition(true));
 
  +
ACDebug.LogWarning("Character " + name + " cannot pathfind without a NavMeshAgent that is on the NavMesh - teleporting instead.", gameObject);
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#8ae233;">Camera</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">main</span><span style="color:#d3d7ce;"> !</span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">null</span><span style="color:#d3d7ce;">)</span>
 
  +
}
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
break;
<span style="color:#d3d7ce;">            </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">calculate</span><span style="color:#888a85;"> </span><span style="color:#888a85;">camera</span><span style="color:#888a85;"> </span><span style="color:#888a85;">relative</span><span style="color:#888a85;"> </span><span style="color:#888a85;">direction</span><span style="color:#888a85;"> </span><span style="color:#888a85;">to</span><span style="color:#888a85;"> </span><span style="color:#888a85;">move</span><span style="color:#888a85;">:</span>
 
  +
<span style="color:#d3d7ce;">            </span><span style="font-style:italic;color:#d3d7ce;">m_CamForward</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">Scale</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#8ae233;">Camera</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">main</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">transform</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">forward</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">new</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;">(</span><span style="color:#edd400;">1</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="color:#edd400;">0</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="color:#edd400;">1</span><span style="color:#d3d7ce;">))</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">normalized</span><span style="color:#d3d7ce;">;</span>
 
  +
case ControlState.ACTurning:
<span style="color:#d3d7ce;">            </span><span style="font-style:italic;color:#d3d7ce;">m_Move</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">v</span><span style="color:#d3d7ce;">*</span><span style="font-style:italic;color:#d3d7ce;">m_CamForward</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">+</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">h</span><span style="color:#d3d7ce;">*</span><span style="color:#8ae233;">Camera</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">main</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">transform</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">right</span><span style="color:#d3d7ce;">;</span>
 
  +
characterTP.Move (Vector3.zero, false, false);
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
break;
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">else</span>
 
  +
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
default:
<span style="color:#d3d7ce;">            </span><span style="font-style:italic;color:#d3d7ce;">m_Move</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">v</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">*</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">forward</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">+</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">h</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">*</span><span style="color:#d3d7ce;"> </span><span style="color:#8ae233;">Vector3</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">right</span><span style="color:#d3d7ce;">;</span>
 
  +
break;
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
}
 
  +
}
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#8ae233;">Input</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">GetKey</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="color:#8ae233;">KeyCode</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">LeftShift</span><span style="color:#d3d7ce;">))</span>
 
  +
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
private void UpdateDirectInput()
<span style="color:#d3d7ce;">            </span><span style="font-style:italic;color:#d3d7ce;">m_Move</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">*=</span><span style="color:#d3d7ce;"> </span><span style="color:#edd400;">0.5f</span><span style="color:#d3d7ce;">;</span>
 
  +
{
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
float h = Input.GetAxis ("Horizontal");
 
  +
float v = Input.GetAxis ("Vertical");
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">characterTP</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">Move</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">m_Move</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">crouch</span><span style="color:#d3d7ce;">,</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">m_Jump</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
bool crouch = Input.GetKey(KeyCode.C);
<span style="color:#d3d7ce;">        </span><span style="font-style:italic;color:#d3d7ce;">m_Jump</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">false</span><span style="color:#d3d7ce;">;</span>
 
  +
if (m_mainCamera != null)
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">}</span>
 
  +
{
 
  +
// calculate camera relative direction to move:
 
  +
if (KickStarter.settingsManager.directMovementPerspective)
<span style="color:#d3d7ce;">    </span><span style="font-weight:700;color:#ad7fa7;">private</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ad7fa7;">void</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">OnTeleport</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">()</span>
 
  +
{
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">{</span>
 
  +
Vector3 forwardVector = (characterAC.transform.position - m_mainCamera.transform.position).normalized;
<span style="color:#d3d7ce;">        </span><span style="color:#888a85;">//</span><span style="color:#888a85;"> </span><span style="color:#888a85;">This</span><span style="color:#888a85;"> </span><span style="color:#888a85;">function</span><span style="color:#888a85;"> </span><span style="color:#888a85;">is</span><span style="color:#888a85;"> </span><span style="color:#888a85;">called</span><span style="color:#888a85;"> </span><span style="color:#888a85;">by</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">Char</span><span style="color:#888a85;"> </span><span style="color:#888a85;">script</span><span style="color:#888a85;"> </span><span style="color:#888a85;">whenever</span><span style="color:#888a85;"> </span><span style="color:#888a85;">the</span><span style="color:#888a85;"> </span><span style="color:#888a85;">character</span><span style="color:#888a85;"> </span><span style="color:#888a85;">has</span><span style="color:#888a85;"> </span><span style="color:#888a85;">been</span><span style="color:#888a85;"> </span><span style="color:#888a85;">teleported</span><span style="color:#888a85;">.</span>
 
  +
Vector3 rightVector = -Vector3.Cross(forwardVector, m_mainCamera.transform.up);
<span style="color:#d3d7ce;">        </span><span style="font-weight:700;color:#ffffff;">if</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;"> !</span><span style="color:#d3d7ce;">=</span><span style="color:#d3d7ce;"> </span><span style="font-weight:700;color:#ce5c00;">null</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">&&</span><span style="color:#d3d7ce;"> </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">isOnNavMesh</span><span style="color:#d3d7ce;">)</span>
 
  +
m_Move = (v * forwardVector) + (h * rightVector);
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">{</span>
 
  +
}
<span style="color:#d3d7ce;">            </span><span style="font-style:italic;color:#d3d7ce;">navMeshAgent</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">Warp</span><span style="color:#d3d7ce;"> </span><span style="color:#d3d7ce;">(</span><span style="font-style:italic;color:#d3d7ce;">transform</span><span style="color:#d3d7ce;">.</span><span style="font-style:italic;color:#d3d7ce;">position</span><span style="color:#d3d7ce;">)</span><span style="color:#d3d7ce;">;</span>
 
  +
else
<span style="color:#d3d7ce;">        </span><span style="color:#d3d7ce;">}</span>
 
  +
{
<span style="color:#d3d7ce;">    </span><span style="color:#d3d7ce;">}</span>
 
  +
m_CamForward = Vector3.Scale(m_mainCamera.transform.forward, new Vector3(1, 0, 1)).normalized;
 
  +
m_Move = v * m_CamForward + h * m_mainCamera.transform.right;
<span style="color:#d3d7ce;">}</span>
 
  +
}
  +
}
  +
else
  +
{
  +
m_Move = v * Vector3.forward + h * Vector3.right;
  +
}
  +
if (Input.GetKey(KeyCode.LeftShift))
  +
{
  +
m_Move *= 0.5f;
  +
}
  +
characterTP.Move (m_Move, crouch, m_Jump);
  +
m_Jump = false;
  +
}
  +
  +
private void OnTeleport()
  +
{
  +
if (navMeshAgent != null && navMeshAgent.isOnNavMesh)
  +
{
  +
navMeshAgent.Warp(transform.position);
  +
}
  +
}
  +
  +
void OnAnimatorMove()
  +
{
  +
if (navMeshAgent != null)
  +
{
  +
agentPosition.x = transform.localPosition.x;
  +
agentPosition.y = navMeshAgent.nextPosition.y;
  +
agentPosition.z = transform.localPosition.z;
  +
navMeshAgent.nextPosition = agentPosition;
  +
}
  +
}
  +
  +
void SetCharacterPath(Char character, Paths paths)
  +
{
  +
navMeshAgent.SetDestination (characterAC.GetTargetPosition (true));
  +
}
  +
  +
}
  +
</syntaxhighlight>
  +
[[Category:Integrations]]

Latest revision as of 07:22, 12 October 2021

This script allows for integration with Unity's own Third Person Controller, which is included in their own Standard Assets package.  It can be used to move a character with both Direct and Point And Click methods, using the Third Person Controller script.

To use it:

  1. Take the existing ThirdPersonController or AIThirdPersonController prefab, and remove any existing control script (with ThirdPersonController, this is ThirdPersonUserControl; with AIThirdPersonController, this is AICharacterControl).
  2. Attach either AC's Player or NPC component
  3. In AC's Settings Manager, set your game's Movement method to either Point And Click or Direct
  4. Attach the script below to the character's root object
  5. (Optional) To allow for AC-controlled movement during e.g. cutscenes, also attach and configure a NavMeshAgent.  The scene must also rely on Unity Navigation pathfinding, as covered in the AC Manual.

UnityThirdPersonIntegration.cs:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using UnityStandardAssets.Characters.ThirdPerson;
using AC;

public class UnityThirdPersonIntegration : MonoBehaviour
{

	private NavMeshAgent navMeshAgent;
	private AC.Char characterAC;
	private AC.Paths characterPaths;
	private ThirdPersonCharacter characterTP;
	private enum ControlState { UnderDirectControl, UnityPathfinding, ACTurning };
	private ControlState controlState = ControlState.ACTurning;
	private Vector3 m_CamForward;
	private Vector3 m_Move;
	private bool m_Jump;
	private float m_moveMultiplier = 0.5f;
	private Camera m_mainCamera;
	private Vector3 agentPosition = Vector3.zero;
	private MotionControl originalMotionControl;

	private void Awake()
	{
		m_mainCamera = KickStarter.CameraMain;
		navMeshAgent = GetComponent<NavMeshAgent>();
		if (navMeshAgent != null)
		{
			navMeshAgent.updateRotation = false;
			navMeshAgent.updatePosition = false;
		}
		characterAC = GetComponent<Char>();
		originalMotionControl = characterAC.motionControl;
		characterAC.motionControl = MotionControl.JustTurning;
		characterPaths = GetComponent<Paths>();
		characterTP = GetComponent<ThirdPersonCharacter>();
	}

	private void OnEnable ()
	{
		characterAC = GetComponent<Char>();
		originalMotionControl = characterAC.motionControl;
		characterAC.motionControl = MotionControl.JustTurning;

		EventManager.OnCharacterSetPath += SetCharacterPath;
	}

	private void OnDisable ()
	{
		characterAC.motionControl = originalMotionControl;
		EventManager.OnCharacterSetPath -= SetCharacterPath;
	}

	private void Update()
	{
		UpdateControlState();
		UpdateMovement();
	}

	private void FixedUpdate()
	{
		if (controlState == ControlState.UnderDirectControl)
		{
			// Do all the input checks for direct input
			UpdateDirectInput();
		}
	}

	private void UpdateControlState()
	{
		if (!KickStarter.stateHandler.IsInGameplay() || !characterAC.IsPlayer || characterAC.IsMovingAlongPath() || KickStarter.settingsManager.movementMethod == MovementMethod.PointAndClick)
		{
			if (characterAC.charState == CharState.Move)
			{
				controlState = ControlState.UnityPathfinding;
			}
			else
			{
				controlState = ControlState.ACTurning;
			}
		}
		else
		{
			controlState = ControlState.UnderDirectControl;
		}
	}

	private void UpdateMovement()
	{
		switch (controlState)
		{
			case ControlState.UnderDirectControl:
				if (navMeshAgent != null)
				{
					 navMeshAgent.enabled = false;
				}
				else
				{
					 ACDebug.LogWarning("A NavMeshAgent component is required on " + gameObject.name, this);
				}
				if (!m_Jump)
				{
					 m_Jump = Input.GetButtonDown("Jump");
				}
				break;

			case ControlState.UnityPathfinding:
				if (navMeshAgent != null)
				{
					 navMeshAgent.enabled = true;
				}
				if (navMeshAgent != null && navMeshAgent.isOnNavMesh)
				{
					 if (navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance)
					 {
						if (characterAC.isRunning)
						{
								m_moveMultiplier = 1.0f;
						}
						else
						{
								m_moveMultiplier = 0.5f;
						}
						characterTP.Move(navMeshAgent.desiredVelocity * m_moveMultiplier, false, false);
					 }
					 else
					 {
						characterTP.Move(Vector3.zero, false, false);
					 }
				}
				else
				{
					 characterAC.Teleport(characterAC.GetTargetPosition(true));
					 ACDebug.LogWarning("Character " + name + " cannot pathfind without a NavMeshAgent that is on the NavMesh - teleporting instead.", gameObject);
				}
				break;

			case ControlState.ACTurning:
				characterTP.Move (Vector3.zero, false, false);
				break;

			default:
				break;
		}
	}

	private void UpdateDirectInput()
	{
		float h = Input.GetAxis ("Horizontal");
		float v = Input.GetAxis ("Vertical");
		bool crouch = Input.GetKey(KeyCode.C);
		if (m_mainCamera != null)
		{
			// calculate camera relative direction to move:
			if (KickStarter.settingsManager.directMovementPerspective)
			{
				Vector3 forwardVector = (characterAC.transform.position - m_mainCamera.transform.position).normalized;
				Vector3 rightVector = -Vector3.Cross(forwardVector, m_mainCamera.transform.up);
				m_Move = (v * forwardVector) + (h * rightVector);
			}
			else
			{
				m_CamForward = Vector3.Scale(m_mainCamera.transform.forward, new Vector3(1, 0, 1)).normalized;
				m_Move = v * m_CamForward + h * m_mainCamera.transform.right;
			}
		}
		else
		{
			m_Move = v * Vector3.forward + h * Vector3.right;
		}
		if (Input.GetKey(KeyCode.LeftShift))
		{
			m_Move *= 0.5f;
		}
		characterTP.Move (m_Move, crouch, m_Jump);
		m_Jump = false;
	}

	private void OnTeleport()
	{
		if (navMeshAgent != null && navMeshAgent.isOnNavMesh)
		{
			navMeshAgent.Warp(transform.position);
		}
	}

	void OnAnimatorMove()
	{
		if (navMeshAgent != null)
		{
			agentPosition.x = transform.localPosition.x;
			agentPosition.y = navMeshAgent.nextPosition.y;
			agentPosition.z = transform.localPosition.z;
			navMeshAgent.nextPosition = agentPosition;
		}
	}

	void SetCharacterPath(Char character, Paths paths)
	{
		 navMeshAgent.SetDestination (characterAC.GetTargetPosition (true));
	}

}