Adventure Creator Wikia
Advertisement

The following Action is an alternative to the Character: Face object Action, and lets you define an Animation Curve that describes the exact rate at which the character turns.

To install:

  1. Copy/paste the code below into a new C# script named ActionCharFaceCurve, and place in a unique folder
  2. Point to this folder in the Actions Manager's Custom Actions section
  3. Use the new Character: Face object curve Action

ActionCharFaceCurve.cs:

using UnityEngine;
using System.Collections.Generic;

#if UNITY_EDITOR
using UnityEditor;
#endif

namespace AC
{

	[System.Serializable]
	public class ActionCharFaceCurve : Action
	{

		public int charToMoveParameterID = -1;
		public int faceObjectParameterID = -1;

		public int charToMoveID = 0;
		public int faceObjectID = 0;

		public AnimationCurve customCurve = new AnimationCurve (new Keyframe(0, 0), new Keyframe(1, 1));

		public Char charToMove;
		protected Char runtimeCharToMove;
		public GameObject faceObject;
		protected GameObject runtimeFaceObject;
		public bool copyRotation;

		public bool facePlayer;
		public int facePlayerID = -1;
	   
		public bool isPlayer;
		public int playerID = -1;
		public int playerParameterID = -1;

		private float startTime;
		private Vector3 startLookDirection;


		public override ActionCategory Category { get { return ActionCategory.Character; }}
		public override string Title { get { return "Face object"; }}
		public override string Description { get { return "Makes a Character turn, either instantly or over time. Can turn to face another object, or copy that object's facing direction."; }}


		public override void AssignValues (List<ActionParameter> parameters)
		{		  
			if (isPlayer)
			{
				runtimeCharToMove = AssignPlayer (playerID, parameters, playerParameterID);
			}
			else
			{
				runtimeCharToMove = AssignFile <Char> (parameters, charToMoveParameterID, charToMoveID, charToMove);
			}

			if (facePlayer)
			{
				Player _player = AssignPlayer (facePlayerID, parameters, faceObjectParameterID);
				runtimeFaceObject = (_player != null) ? _player.gameObject : null;
			}
			else
			{
				runtimeFaceObject = AssignFile (parameters, faceObjectParameterID, faceObjectID, faceObject);
			}
		}

	   
		public override float Run ()
		{
			if (!isRunning)
			{
				isRunning = true;
		   
				if (runtimeFaceObject == null || runtimeCharToMove == null)
				{
					return 0f;
				}

				if (runtimeCharToMove.IsMovingAlongPath ())
				{
					runtimeCharToMove.EndPath ();
				}

				startTime = Time.time;
				startLookDirection = runtimeCharToMove.transform.forward;
				bool isFinished = ApplyCurve ();
				return isFinished ? 0f : defaultPauseTime;
			}
			else
			{
				if (ApplyCurve ())
				{
					isRunning = false;
					return 0f;
				}
				return defaultPauseTime;
			}
		}


		public override void Skip ()
		{
			if (runtimeCharToMove && runtimeFaceObject)
			{
				runtimeCharToMove.SetLookDirection (GetLookVector (), true);
			}
		}


		private bool ApplyCurve ()
		{
			Vector3 endDirection = GetLookVector ();
			float timeValue = Time.time - startTime;
			float endTime = customCurve.keys[customCurve.keys.Length - 1].time;

			if (timeValue >= endTime)
			{
				runtimeCharToMove.SetLookDirection (endDirection, true);
				return true;
			}

			float amount = customCurve.Evaluate (timeValue);
			Vector3 lookDirection = Vector3.Slerp (startLookDirection, endDirection, amount);
			runtimeCharToMove.SetLookDirection (lookDirection, true);
			return false;
		}

	   
		protected Vector3 GetLookVector ()
		{
			if (copyRotation)
			{
				Marker runtimeMarker = runtimeFaceObject.GetComponent <Marker>();
				if (runtimeMarker)
				{
					return runtimeMarker.ForwardDirection;
				}

				return runtimeFaceObject.transform.forward;
			}

			Hotspot faceObjectHotspot = runtimeFaceObject.GetComponent<Hotspot> ();
			if (faceObjectHotspot && faceObjectHotspot.centrePoint && faceObjectHotspot.centrePointOverrides != CentrePointOverrides.IconPositionOnly)
			{
				runtimeFaceObject = faceObjectHotspot.centrePoint.gameObject;
			}
		   
			if (SceneSettings.ActInScreenSpace ())
			{
				return AdvGame.GetScreenDirection (runtimeCharToMove.Transform.position, runtimeFaceObject.transform.position);
			}
		   
			return runtimeFaceObject.transform.position - runtimeCharToMove.transform.position;
		}


		#if UNITY_EDITOR

		public override void ShowGUI (List<ActionParameter> parameters)
		{
			bool playerSwitching = (KickStarter.settingsManager && KickStarter.settingsManager.playerSwitching == PlayerSwitching.Allow);
		   
			isPlayer = EditorGUILayout.Toggle ("Affect Player?", isPlayer);
			if (isPlayer)
			{
				if (playerSwitching)
				{
					playerParameterID = ChooseParameterGUI ("Player ID:", parameters, playerParameterID, ParameterType.Integer);
					if (playerParameterID < 0)
						playerID = ChoosePlayerGUI (playerID, true);
				}
			}
			else
			{
				charToMoveParameterID = Action.ChooseParameterGUI ("Character to turn:", parameters, charToMoveParameterID, ParameterType.GameObject);
				if (charToMoveParameterID >= 0)
				{
					charToMoveID = 0;
					charToMove = null;
				}
				else
				{
					charToMove = (Char) EditorGUILayout.ObjectField ("Character to turn:", charToMove, typeof(Char), true);
				   
					charToMoveID = FieldToID <Char> (charToMove, charToMoveID);
					charToMove = IDToField <Char> (charToMove, charToMoveID, false);
				}
			}

			if (isPlayer && !playerSwitching)
			{
				facePlayer = false;
			}
			else
			{
				facePlayer = EditorGUILayout.Toggle ("Face player?", facePlayer);

				if (facePlayer)
				{
					if (playerSwitching)
					{
						faceObjectParameterID = ChooseParameterGUI ("Player ID:", parameters, faceObjectParameterID, ParameterType.Integer);
						if (faceObjectParameterID < 0)
							facePlayerID = ChoosePlayerGUI (facePlayerID, true);

						if (isPlayer && playerParameterID < 0 && faceObjectParameterID < 0 && playerID == facePlayerID)
						{
							EditorGUILayout.HelpBox ("A Player cannot face themselves!", MessageType.Warning);
						}
					}
				}
			}

			if (!facePlayer)
			{
				faceObjectParameterID = Action.ChooseParameterGUI ("Object to face:", parameters, faceObjectParameterID, ParameterType.GameObject);
				if (faceObjectParameterID >= 0)
				{
					faceObjectID = 0;
					faceObject = null;
				}
				else
				{
					faceObject = (GameObject) EditorGUILayout.ObjectField ("Object to face:", faceObject, typeof(GameObject), true);
				   
					faceObjectID = FieldToID (faceObject, faceObjectID);
					faceObject = IDToField (faceObject, faceObjectID, false);
				}
			}

			copyRotation = EditorGUILayout.Toggle ("Use object's rotation?", copyRotation);
			customCurve = EditorGUILayout.CurveField ("Curve:", customCurve);
		}


		public override void AssignConstantIDs (bool saveScriptsToo, bool fromAssetFile)
		{
			if (saveScriptsToo)
			{
				if (!isPlayer && charToMove != null && !charToMove.IsPlayer)
				{
					AddSaveScript <RememberNPC> (charToMove);
				}
			}

			if (!isPlayer)
			{
				charToMoveID = AssignConstantID<Char> (charToMove, charToMoveID, charToMoveParameterID);
			}
			faceObjectID = AssignConstantID (faceObject, faceObjectID, faceObjectParameterID);
		}

	   
		public override string SetLabel ()
		{
			if (faceObject != null)
			{
				if (charToMove != null)
				{
					return charToMove.name + " to " + faceObject.name;
				}
				else if (isPlayer)
				{
					return "Player to " + faceObject.name;
				}
			}
			return string.Empty;
		}


		public override bool ReferencesObjectOrID (GameObject _gameObject, int id)
		{
			if (!isPlayer && charToMoveParameterID < 0)
			{
				if (charToMove && charToMove.gameObject == _gameObject) return true;
				if (charToMoveID == id) return true;
			}
			if (isPlayer && _gameObject && _gameObject.GetComponent <Player>()) return true;
			if (!facePlayer && faceObjectParameterID < 0)
			{
				if (faceObject != null && faceObject.gameObject == _gameObject) return true;
				if (faceObjectID == id) return true;
			}
			if (facePlayer && _gameObject && _gameObject.GetComponent <Player>() != null) return true;
			return base.ReferencesObjectOrID (_gameObject, id);
		}


		public override bool ReferencesPlayer (int _playerID = -1)
		{
			if (isPlayer)
			{
				if (_playerID < 0) return true;
				if (playerID < 0 && playerParameterID < 0) return true;
				if (playerParameterID < 0 && playerID == _playerID) return true;
			}
			else if (facePlayer)
			{
				return true;
			}
			return false;
		}

		#endif

	}

}
Advertisement