"ICommand" as "Interface" And CommandList to hold all commands
ICommand Interface;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface ICommand
{
void Execute();
void Undo();
}
CommandList Class (No monoBehaviour inheritance**)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
public class CommandList
{
private const int MAXCOMMAND = 100;
private Stack<ICommand> commandList = new Stack<ICommand>();
public void Execute(ICommand command)
{
command.Execute();
if (commandList.Count < MAXCOMMAND)
commandList.Push(command);
}
public void Undo()
{
if (commandList.Count <= 0)
return;
commandList.Pop().Undo();
}
}
those two classes is main implementation after that you can use
those classes based on your sceneraio;
For example you scale your cube based on your imput
and you move your cube based on your mouse movement
So command will be seperated like "MoveCommand" and
"ScaleCommand"
Move Command (Inherites from ICommand);
public class MoveCommand : ICommand
{
private Transform movingObject;
private Vector3 direction;
private float moveSpeed;
public MoveCommand(Transform transform,Vector3 direction,float moveSpeed)
{
this.movingObject = transform;
this.direction = direction;
this.moveSpeed = moveSpeed;
}
public void Execute()
{
this.movingObject.transform.position += this.direction* moveSpeed;
}
public void Undo()
{
this.movingObject.transform.position -= this.direction* moveSpeed;
}
}
Scale Command(Inherites from ICommand);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScaleCommand : ICommand
{
private float scalefactor;
private Transform transform;
public ScaleCommand(float scalefactor,Transform transform)
{
this.scalefactor = scalefactor;
this.transform = transform;
}
public void Execute()
{
this.transform.localScale += Vector3.one * scalefactor;
}
public void Undo()
{
this.transform.localScale -= Vector3.one * scalefactor;
}
}
To Finalize every thing and combine mechanics togeter you have to call
those classes
let's say "CubeController" to our Main Class
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CubeController : MonoBehaviour
{
// Start is called before the first frame update
[SerializeField]
float moveSpeed;
[SerializeField]
float scaleUpMultiplyer;
Vector3 lastPos;
Vector3 deltaPos;
// Update is called once per frame
CommandList commands = new CommandList();
void Update()
{
MovingInputs();
ScaleInputs();
UndoInput();
}
void ScaleInputs()
{
if (Input.GetKeyDown(KeyCode.A))
{
commands.Execute(new ScaleCommand(scaleUpMultiplyer, this.transform));
}
}
void UndoInput()
{
if (Input.GetKey(KeyCode.Q))
{
commands.Undo();
}
if (Input.GetKeyDown(KeyCode.Z))
{
commands.Undo();
}
}
void MovingInputs()
{
if (Input.GetMouseButtonDown(0))
{
lastPos = Input.mousePosition;
}
else if (Input.GetMouseButton(0))
{
deltaPos = Input.mousePosition - lastPos;
commands.Execute(new MoveCommand(this.transform, deltaPos, moveSpeed));
}
}
}
you can do commands and undo commands with this system every new mechanic will be Inherited from ICommand like Coloring Cube,RotatingCube and can be Undo using CommandList
Feel Free to ask any questions :)
Happy Coding :)
No comments:
Post a Comment