I am trying to create a simple ObjectMover class to move objects within a base (think Clash of Clans base editing).
The issue I am having is that when an object is selected using a RayCast it jumps to the RayCast hit.point as the collider for the object can be hit on the edge and will then move to be centered on the hit.point.
I have tried using an offset and am sure it is something trivial but having a brain fart and not able to find the solution.
ObjectMover.cs
using UnityEngine;
using System.Collections;
public class ObjectMover : MonoBehaviour
{
#pragma warning disable 0649
[SerializeField] private GameObject _tmpObjectToMove;
[SerializeField] private LayerMask _groundLayerMask;
[SerializeField] private LayerMask _objectsLayerMask;
#pragma warning restore 0649
private Camera _cam;
private GameObject _movableObject;
private bool _objectIsSelected;
private Vector3 _objectSelectionOffset;
private void Awake()
{
_cam = Camera.main;
}
private void Start()
{
//TMP call and object instantiation for testing purposes
GameObject obj = Instantiate(_tmpObjectToMove, Vector3.zero, Quaternion.identity);
MakeObjectMoveable(obj);
}
private IEnumerator UpdatePosition()
{
while (_movableObject != null)
{
if (Input.GetButtonDown("Fire1"))
{
TestObjectSelection();
}
else if (Input.GetButtonUp("Fire1"))
{
if (_objectIsSelected)
{
_objectIsSelected = false;
}
}
if (_objectIsSelected)
{
_movableObject.transform.position = GetNewPosition();
}
yield return null;
}
}
public void MakeObjectMoveable(GameObject objectToMakeMovable)
{
_movableObject = objectToMakeMovable;
StartCoroutine(UpdatePosition());
}
private Vector3 GetNewPosition()
{
if (_movableObject != null)
{
Ray ray = _cam.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray.origin, ray.direction, out RaycastHit hitInfo, 200f, _groundLayerMask, QueryTriggerInteraction.Ignore))
{
Vector3 pos = hitInfo.point - _objectSelectionOffset;
return new Vector3(pos.x, 0f, pos.z);
}
}
return _movableObject.transform.position;
}
private void TestObjectSelection()
{
Ray ray = _cam.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray.origin, ray.direction, out RaycastHit hitInfo, 200f, _objectsLayerMask, QueryTriggerInteraction.Ignore))
{
if (hitInfo.transform.gameObject == _movableObject)
{
Vector3 difference = hitInfo.point - _movableObject.transform.position;
_objectSelectionOffset = new Vector3(difference.x, 0f, difference.z);
_objectIsSelected = true;
}
}
}
}
What am I not seeing?