Adventure Creator Wikia
No edit summary
Tag: Visual edit
No edit summary
Tag: Visual edit
 
(2 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 [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.
+
This script allows for integration with Unity's [https://assetstore.unity.com/packages/essentials/starter-assets-third-person-character-controller-196526 Starter Assets - Third Person Controller] asset.
   
 
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''').
 
#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 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.<br>
 
   
  +
# Import AC into a project that is already set up with the Third Person Controller asset
UnityThirdPersonIntegration.cs:<syntaxhighlight lang="csharp">
 
  +
# Copy/paste the script below into a C# file named StarterAssetsInput_AC
using System.Collections;
 
  +
# Locate the asset's PlayerArmature prefab, and remove its Starter Assets Input component
using System.Collections.Generic;
 
  +
# Add the new Starter Assets Input AC component, as well as AC's Player component
  +
# In the Player component's Inspector, set the Animation engine to Mecanim, and clear the parameter fields beneath
  +
 
StarterAssetsInput_AC.cs:<syntaxhighlight lang="csharp">
 
using UnityEngine;
 
using UnityEngine;
  +
#if ENABLE_INPUT_SYSTEM
using UnityEngine.AI;
+
using UnityEngine.InputSystem;
using UnityStandardAssets.Characters.ThirdPerson;
 
  +
#endif
 
using AC;
 
using AC;
   
  +
namespace StarterAssets
public class UnityThirdPersonIntegration : MonoBehaviour
 
 
{
 
{
 
 
  +
public class StarterAssetsInputs_AC : StarterAssetsInputs
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 void Awake()
 
 
{
 
{
 
m_mainCamera = KickStarter.CameraMain;
 
  +
public bool acTurnsCamera;
navMeshAgent = GetComponent<NavMeshAgent>();
 
 
if (navMeshAgent != null)
 
  +
AC.Char acCharacter;
  +
bool underACControl;
 
 
void Awake ()
 
{
 
{
 
acCharacter = GetComponent<AC.Char> ();
navMeshAgent.updateRotation = false;
 
 
acCharacter.motionControl = MotionControl.Manual;
navMeshAgent.updatePosition = false;
 
 
}
 
}
 
characterAC = GetComponent<Char>();
 
 
void Update ()
characterAC.motionControl = MotionControl.JustTurning;
 
characterPaths = GetComponent<Paths>();
 
characterTP = GetComponent<ThirdPersonCharacter>();
 
}
 
 
private void OnEnable ()
 
{
 
EventManager.OnCharacterSetPath += SetCharacterPath;
 
}
 
 
private void OnDisable ()
 
{
 
EventManager.OnCharacterSetPath -= SetCharacterPath;
 
}
 
 
private void Update()
 
{
 
UpdateControlState();
 
UpdateMovement();
 
}
 
 
private void FixedUpdate()
 
{
 
if (controlState == ControlState.UnderDirectControl)
 
 
{
 
{
  +
underACControl = !KickStarter.stateHandler.IsInGameplay () ||
// Do all the input checks for direct input
 
 
(!acCharacter.IsPlayer || KickStarter.settingsManager.movementMethod == MovementMethod.PointAndClick) ||
UpdateDirectInput();
 
  +
acCharacter.IsMovingAlongPath ();
}
 
 
}
 
  +
if (underACControl)
 
private void UpdateControlState()
 
{
 
if (!KickStarter.stateHandler.IsInGameplay() || !characterAC.IsPlayer || characterAC.IsMovingAlongPath() || KickStarter.settingsManager.movementMethod == MovementMethod.PointAndClick)
 
{
 
if (characterAC.charState == CharState.Move)
 
 
{
 
{
  +
Vector3 moveDirection = acCharacter.GetTargetPosition () - transform.position;
controlState = ControlState.UnityPathfinding;
 
  +
MoveInput (moveDirection);
}
 
else
+
 
if (acTurnsCamera)
{
+
{
controlState = ControlState.ACTurning;
 
  +
Vector3 lookDirection = acCharacter.GetTargetRotation () * Vector3.forward;
  +
lookDirection.y = 0f;
  +
LookInput (lookDirection);
 
}
 
}
 
}
 
}
 
}
else
+
  +
private Vector2 GetInputVector (Vector3 worldDirection)
 
{
 
{
  +
worldDirectionworldDirection.y = 0f;
controlState = ControlState.UnderDirectControl;
 
  +
if (worldDirection.sqrMagnitude > 1f) worldDirection.Normalize ();
}
 
  +
Vector3 cameraForward = KickStarter.CameraMainTransform.forward;
}
 
  +
cameraForward.y = 0f;
  +
cameraForward.Normalize ();
   
  +
Vector3 cameraRight = KickStarter.CameraMainTransform.right;
private void UpdateMovement()
 
  +
cameraRight.y = 0f;
{
 
  +
cameraRight.Normalize ();
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;
 
   
  +
float forwardAmount = Vector3.Dot (cameraForward, worldDirection.normalized);
case ControlState.UnityPathfinding:
 
  +
float rightAmount = Vector3.Dot (cameraRight, worldDirection.normalized);
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;
 
   
  +
return new Vector2 (rightAmount, forwardAmount);
case ControlState.ACTurning:
 
 
}
characterTP.Move (Vector3.zero, false, false);
 
break;
 
   
  +
#if ENABLE_INPUT_SYSTEM
default:
 
  +
public new void OnMove(InputValue value)
break;
 
 
{
  +
if (underACControl) return;
  +
MoveInput(value.Get<Vector2>());
 
}
 
}
}
 
   
  +
public new void OnLook(InputValue value)
private void UpdateDirectInput()
 
{
 
float h = Input.GetAxis ("Horizontal");
 
float v = Input.GetAxis ("Vertical");
 
bool crouch = Input.GetKey(KeyCode.C);
 
if (m_mainCamera != null)
 
 
{
 
{
  +
if(cursorInputForLook)
// 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
 
 
{
 
{
  +
LookInput(value.Get<Vector2>());
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;
 
}
 
   
  +
public new void OnJump(InputValue value)
private void OnTeleport()
 
{
 
if (navMeshAgent != null && navMeshAgent.isOnNavMesh)
 
 
{
 
{
  +
if (underACControl) return;
navMeshAgent.Warp(transform.position);
 
  +
JumpInput(value.isPressed);
 
}
 
}
}
 
   
  +
public new void OnSprint(InputValue value)
void OnAnimatorMove()
 
{
 
if (navMeshAgent != null)
 
 
{
 
{
  +
if (underACControl) { SprintInput (acCharacter.isRunning); return; }
agentPosition.x = transform.localPosition.x;
 
  +
SprintInput(value.isPressed);
agentPosition.y = navMeshAgent.nextPosition.y;
 
agentPosition.z = transform.localPosition.z;
 
navMeshAgent.nextPosition = agentPosition;
 
 
}
 
}
  +
#endif
}
 
   
void SetCharacterPath(Char character, Paths paths)
 
{
 
navMeshAgent.SetDestination (characterAC.GetTargetPosition (true));
 
 
}
 
}
 
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 05:56, 27 September 2023

This script allows for integration with Unity's Starter Assets - Third Person Controller asset.

To use it:

  1. Import AC into a project that is already set up with the Third Person Controller asset
  2. Copy/paste the script below into a C# file named StarterAssetsInput_AC
  3. Locate the asset's PlayerArmature prefab, and remove its Starter Assets Input component
  4. Add the new Starter Assets Input AC component, as well as AC's Player component
  5. In the Player component's Inspector, set the Animation engine to Mecanim, and clear the parameter fields beneath

StarterAssetsInput_AC.cs:

using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
using AC;

namespace StarterAssets
{
	
	public class StarterAssetsInputs_AC : StarterAssetsInputs
	{
	
		public bool acTurnsCamera;
	
		AC.Char acCharacter;
		bool underACControl;
		
		void Awake ()
		{
			acCharacter = GetComponent<AC.Char> ();
			acCharacter.motionControl = MotionControl.Manual;
		}
		
		void Update ()
		{
			underACControl = !KickStarter.stateHandler.IsInGameplay () ||
							 (!acCharacter.IsPlayer || KickStarter.settingsManager.movementMethod == MovementMethod.PointAndClick) ||
							 acCharacter.IsMovingAlongPath ();
				
			if (underACControl)
			{
				Vector3 moveDirection = acCharacter.GetTargetPosition () - transform.position;
				MoveInput (moveDirection);
			
				if (acTurnsCamera)
				{
					Vector3 lookDirection = acCharacter.GetTargetRotation () * Vector3.forward;
					lookDirection.y = 0f;
					LookInput (lookDirection);
				}
			}
		}
		
		private Vector2 GetInputVector (Vector3 worldDirection)
		{
			worldDirectionworldDirection.y = 0f;
			if (worldDirection.sqrMagnitude > 1f) worldDirection.Normalize ();
			Vector3 cameraForward = KickStarter.CameraMainTransform.forward;
			cameraForward.y = 0f;
			cameraForward.Normalize ();

			Vector3 cameraRight = KickStarter.CameraMainTransform.right;
			cameraRight.y = 0f;
			cameraRight.Normalize ();

			float forwardAmount = Vector3.Dot (cameraForward, worldDirection.normalized);
			float rightAmount = Vector3.Dot (cameraRight, worldDirection.normalized);

			return new Vector2 (rightAmount, forwardAmount);
		}

#if ENABLE_INPUT_SYSTEM
		public new void OnMove(InputValue value)
		{
			if (underACControl) return;
			MoveInput(value.Get<Vector2>());
		}

		public new void OnLook(InputValue value)
		{
			if(cursorInputForLook)
			{
				LookInput(value.Get<Vector2>());
			}
		}

		public new void OnJump(InputValue value)
		{
			if (underACControl) return;
			JumpInput(value.isPressed);
		}

		public new void OnSprint(InputValue value)
		{
			if (underACControl) { SprintInput (acCharacter.isRunning); return; }
			SprintInput(value.isPressed);
		}
#endif

	}
	
}