Reputation: 11
I was rewriting some code to practice SOLID and I think my code is failing the Liskov Substitution Principle. I don't know if this code is correct, can someone help me?
That code was created to control camera rotation, position and orientation for a thir person character. I don't know if that methods need to be separated in other classes or if this code is correct.
Obs: That class control the anchor but I don't know it is correct if all this methods should be in the same place.
Class:
public class AnchorControlForThirdPersonCamera : MonoBehaviour, IAnchorControlForThirdPersonCamera
{
[Header("Settings")]
[SerializeField] private string anchorName = "CameraAnchor";
[SerializeField] private Vector3 offset = new Vector3(0,1,0);
[Header("Rotation Control")]
[SerializeField] private string inpMouseX = "Mouse X";
[SerializeField] private string inpMouseY = "Mouse Y";
[SerializeField] private float rotationSpeed = 100;
[SerializeField,Range(1,179)] private float minAxisY = 89;
[SerializeField,Range(181,359)] private float maxAxisY = 320;
private Transform anchor;
public Transform GetAnchor() {
return anchor;
}
public void CreateAnchor()
{
if (!anchor)
{
anchor = new GameObject(anchorName).transform;
anchor.hideFlags = HideFlags.HideInHierarchy;
}
}
public void CalculateEulerForAnchorRotation()
{
float axisMouseX = Input.GetAxis(inpMouseX);
float axisMouseY = Input.GetAxis(inpMouseY);
Vector3 anchorEuler = anchor.eulerAngles;
anchorEuler.y += axisMouseX * rotationSpeed * Time.fixedDeltaTime;
anchorEuler.x -= axisMouseY * rotationSpeed * Time.fixedDeltaTime;
if (anchorEuler.x > minAxisY && anchorEuler.x < 180) anchorEuler.x = minAxisY;
if (anchorEuler.x < maxAxisY && anchorEuler.x > 180) anchorEuler.x = maxAxisY;
anchor.eulerAngles = anchorEuler;
}
public void CalculateAnchorPosition(Transform player)
{
anchor.position = player.TransformPoint(offset);
}
public void OnDestroyAnchor()
{
if (anchor)
{
Destroy(anchor);
}
}
}
Interface:
public interface IAnchorControlForThirdPersonCamera
{
Transform GetAnchor();
void CreateAnchor();
/// <summary></summary>
void CalculateEulerForAnchorRotation();
/// <summary>Used in LateUpdate method.</summary>
/// <param name="player"></param>
void CalculateAnchorPosition(Transform player);
void OnDestroyAnchor();
}
Main Code:
public class ThirdPersonCamera : MonoBehaviour
{
private IAnchorControlForThirdPersonCamera _anchorControl;
private ICameraPositionRayForThirdPersonCamera _cameraPositionRay;
private ICameraPositionForThirdPersonCamera _cameraPosition;
private ICameraOrientationForThirdPersonCamera _cameraOrientation;
[SerializeField] private Transform player;
private RaycastHit hitForCameraPos = new RaycastHit();
private Ray rayForCameraPos;
private void Awake()
{
if (GetComponent<ICameraPositionRayForThirdPersonCamera>() == null)
{
gameObject.AddComponent<CameraPositionRayForThirdPersonCamera>();
}
_cameraPositionRay = GetComponent<ICameraPositionRayForThirdPersonCamera>();
if (GetComponent<IAnchorControlForThirdPersonCamera>() == null) {
gameObject.AddComponent<AnchorControlForThirdPersonCamera>();
}
_anchorControl = GetComponent<IAnchorControlForThirdPersonCamera>();
if (GetComponent<ICameraPositionForThirdPersonCamera>() == null)
{
gameObject.AddComponent<CameraPositionForThirdPersonCamera>();
}
_cameraPosition = GetComponent<ICameraPositionForThirdPersonCamera>();
if (GetComponent<ICameraOrientationForThirdPersonCamera>() == null)
{
gameObject.AddComponent<CameraOrientationForThirdPersonCamera>();
}
_cameraOrientation = GetComponent<ICameraOrientationForThirdPersonCamera>();
_anchorControl.CreateAnchor();
}
void Start() {
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
Transform anchor = _anchorControl.GetAnchor();
_anchorControl.CalculateEulerForAnchorRotation();
rayForCameraPos = _cameraPositionRay.CreateRayForCameraPosition(anchor);
hitForCameraPos = _cameraPosition.SpherecastForCalculateCameraPosition(rayForCameraPos);
_anchorControl.CalculateAnchorPosition(player);
rayForCameraPos = _cameraPositionRay.CreateRayForCameraPosition(anchor);
transform.position = _cameraPosition.GetCameraPosition(rayForCameraPos, hitForCameraPos);
transform.rotation = _cameraOrientation.GetCameraLookAtTargetPoint(anchor, transform);
}
void Update() {
_anchorControl.CreateAnchor();
_anchorControl.CalculateEulerForAnchorRotation();
rayForCameraPos = _cameraPositionRay.CreateRayForCameraPosition(_anchorControl.GetAnchor());
hitForCameraPos = _cameraPosition.SpherecastForCalculateCameraPosition(rayForCameraPos);
}
void LateUpdate()
{
Transform anchor = _anchorControl.GetAnchor();
_anchorControl.CalculateAnchorPosition(player);
rayForCameraPos = _cameraPositionRay.CreateRayForCameraPosition(anchor);
transform.position = _cameraPosition.GetCameraPosition(rayForCameraPos, hitForCameraPos);
transform.rotation = _cameraOrientation.GetCameraLookAtTargetPoint(anchor, transform);
}
private void OnDestroy() {
_anchorControl.OnDestroyAnchor();
}
}
I tryed to implement liskov subistituition principle in this code, but when I tryed to implement in the methods related a anchor control (used to control the position, rotation and orientation of the camera) the code become strange and I don't know if I write correctly.
Upvotes: 0
Views: 105