├── ActionHook.cs ├── Actions ├── Action.cs ├── AssignTransform.cs ├── FollowTransform.cs ├── InputAxis.cs └── InputManager.cs ├── README.md ├── State Actions ├── IsGrounded.cs ├── MoveForward.cs ├── MovementAnimations.cs ├── RotateBasedOnCamera.cs └── StateAction.cs ├── State.cs ├── StateManager.cs └── Variables └── TransformVariable.cs /ActionHook.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace SA 6 | { 7 | public class ActionHook : MonoBehaviour 8 | { 9 | public Action[] updateActions; 10 | 11 | void Update() 12 | { 13 | for (int i = 0; i < updateActions.Length; i++) 14 | { 15 | updateActions[i].Execute(); 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Actions/Action.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace SA 6 | { 7 | public abstract class Action : ScriptableObject 8 | { 9 | public abstract void Execute(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Actions/AssignTransform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | public class AssignTransform : MonoBehaviour 9 | { 10 | public TransformVariable transformVariable; 11 | 12 | void Start() 13 | { 14 | transformVariable.value = this.transform; 15 | Destroy(this); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Actions/FollowTransform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | [CreateAssetMenu] 9 | public class FollowTransform : Action 10 | { 11 | public TransformVariable targetTransform; 12 | public TransformVariable currentTransform; 13 | public float speed = 9; 14 | 15 | public override void Execute() 16 | { 17 | if (targetTransform.value == null) 18 | return; 19 | if (currentTransform.value == null) 20 | return; 21 | 22 | Vector3 targetPosition = 23 | Vector3.Lerp(currentTransform.value.position, targetTransform.value.position, Time.deltaTime * speed); 24 | currentTransform.value.position = targetPosition; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Actions/InputAxis.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | [CreateAssetMenu(menuName = "Inputs/Axis")] 9 | public class InputAxis : Action 10 | { 11 | public string targetString; 12 | public float value; 13 | 14 | public override void Execute() 15 | { 16 | value = Input.GetAxis(targetString); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Actions/InputManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | [CreateAssetMenu] 9 | public class InputManager : Action 10 | { 11 | public InputAxis horizontal; 12 | public InputAxis vertical; 13 | 14 | public float moveAmount; 15 | 16 | public override void Execute() 17 | { 18 | horizontal.Execute(); 19 | vertical.Execute(); 20 | 21 | moveAmount = Mathf.Clamp01(Mathf.Abs(horizontal.value) + Math.Abs(vertical.value)); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Strategy-Pattern-in-Unity 2 | An example case of using the strategy design pattern with scriptable objects inside Unity 3 | 4 | You can find more info on this video 5 | https://youtu.be/UjcG0B7JFbM 6 | 7 | Strategy Pattern Wiki 8 | https://en.wikipedia.org/wiki/Strategy_pattern#Strategy_and_open/closed_principle 9 | -------------------------------------------------------------------------------- /State Actions/IsGrounded.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | [CreateAssetMenu] 9 | public class IsGrounded : StateAction 10 | { 11 | public override void Execute(StateManager states) 12 | { 13 | Vector3 origin = states.transform.position; 14 | origin.y += .7f; 15 | Vector3 dir = -Vector3.up; 16 | float dis = 1.4f; 17 | RaycastHit hit; 18 | Debug.DrawRay(origin, dir * dis); 19 | if (Physics.Raycast(origin, dir, out hit, dis)) 20 | { 21 | Vector3 targetPosition = hit.point; 22 | states.transform.position = targetPosition; 23 | } 24 | 25 | } 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /State Actions/MoveForward.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | [CreateAssetMenu] 9 | public class MoveForward : StateAction 10 | { 11 | public InputManager inpManager; 12 | public float movementSpeed = 2; 13 | 14 | public override void Execute(StateManager states) 15 | { 16 | Vector3 velocity = states.mTransform.forward * inpManager.moveAmount * movementSpeed; 17 | states.rigid.velocity = velocity; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /State Actions/MovementAnimations.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | [CreateAssetMenu] 9 | public class MovementAnimations : StateAction 10 | { 11 | public string floatName; 12 | public InputManager inpManager; 13 | 14 | public override void Execute(StateManager states) 15 | { 16 | states.anim.SetFloat(floatName, inpManager.moveAmount, .2f, states.delta); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /State Actions/RotateBasedOnCamera.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using UnityEngine; 5 | 6 | namespace SA 7 | { 8 | [CreateAssetMenu] 9 | public class RotateBasedOnCamera : StateAction 10 | { 11 | public TransformVariable cameraTransform; 12 | public InputManager inpManager; 13 | public float speed = 8; 14 | 15 | public override void Execute(StateManager states) 16 | { 17 | if (cameraTransform.value == null) 18 | return; 19 | 20 | float h = inpManager.horizontal.value; 21 | float v = inpManager.vertical.value; 22 | 23 | Vector3 targetDir = cameraTransform.value.forward * v; 24 | targetDir += cameraTransform.value.right * h; 25 | targetDir.Normalize(); 26 | 27 | targetDir.y = 0; 28 | if (targetDir == Vector3.zero) 29 | targetDir = states.transform.forward; 30 | 31 | Quaternion tr = Quaternion.LookRotation(targetDir); 32 | Quaternion targetRotation = Quaternion.Slerp( 33 | states.transform.rotation, tr, 34 | states.delta * inpManager.moveAmount * speed); 35 | 36 | states.transform.rotation = targetRotation; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /State Actions/StateAction.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace SA 6 | { 7 | public abstract class StateAction : ScriptableObject 8 | { 9 | public abstract void Execute(StateManager states); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /State.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace SA 6 | { 7 | [CreateAssetMenu] 8 | public class State : ScriptableObject 9 | { 10 | public List actions = new List(); 11 | 12 | public void Tick(StateManager states) 13 | { 14 | for (int i = actions.Count -1; i >=0 ; i--) 15 | { 16 | actions[i].Execute(states); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /StateManager.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace SA 6 | { 7 | public class StateManager : MonoBehaviour 8 | { 9 | public State currentState; 10 | 11 | public Transform mTransform; 12 | public Rigidbody rigid; 13 | public Animator anim; 14 | public float delta; 15 | public TransformVariable playerTransform; 16 | 17 | void Start() 18 | { 19 | mTransform = this.transform; 20 | anim = GetComponentInChildren(); 21 | rigid = GetComponent(); 22 | rigid.constraints = RigidbodyConstraints.FreezeRotation; 23 | 24 | if(playerTransform != null) 25 | { 26 | playerTransform.value = mTransform; 27 | } 28 | } 29 | 30 | void Update() 31 | { 32 | delta = Time.deltaTime; 33 | 34 | if(currentState != null) 35 | { 36 | currentState.Tick(this); 37 | } 38 | } 39 | 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Variables/TransformVariable.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | 5 | namespace SA 6 | { 7 | [CreateAssetMenu] 8 | public class TransformVariable : ScriptableObject 9 | { 10 | public Transform value; 11 | 12 | } 13 | } 14 | --------------------------------------------------------------------------------