So, I’m trying to combine information (and code) from tutorials and documentation so that I can properly navigate in my game. This is an example of when my code worked (this was also when I was rotating the globe and not the camera like I should have been.) I put an invisible sphere around the globe that detects when the mouse is clicking on it, set the game camera as a child of that sphere, and the movement of the cursor would make the camera rotate around. However, I want the player to be able to interact with the continents and that would be impossible with the invisible sphere. So I looked up some proper mobile input controls and raycasting. At some point I would like to get it to a point where I can restrict the movement of the camera to prevent “snagging” at the north and south poles.
The code for the Touch Input is as follows:
{
// Designates the layer gameobjects will have to be in for the raycast to trigger
public LayerMask touchInputMask;
// A list of gameobjects that the player can drag across for the purposes of preventing issues when dragging back and forth
private List<GameObject> touchList = new List<GameObject>();
private GameObject[] touchesOld;
private RaycastHit hit;
//Detects input, sends a raycast to a game object, if it is of the touchInputMask layer it receives information about the nature of the user input.
void Update()
{
if (Input.touchCount > 0)
{
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo(touchesOld);
touchList.Clear();
foreach (Touch touch in Input.touches)
{
Ray ray = GetComponent<Camera>().ScreenPointToRay(touch.position);
if (Physics.Raycast(ray, out hit, touchInputMask))
{
GameObject recipient = hit.transform.gameObject;
touchList.Add(recipient);
if (touch.phase == TouchPhase.Began)
{
recipient.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Ended)
{
recipient.SendMessage("OnTouchUp", hit.point, SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved)
{
recipient.SendMessage("OnTouchStay", hit.point, SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Canceled)
{
recipient.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
} }
}
foreach (GameObject g in touchesOld)
{
if (!touchList.Contains(g))
{
g.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver);
}
}
}
}
}
}
The code for the Camera is as follows:
{
// In order: multiplier for rotation vector, two vectors to compare how far it should move in a single frame, and bool to make rotating stop and go
private float _sensitivity;
private Vector2 _inputRef, _inputOff;
private Vector3 _rotation;
private bool _isRotating;
void Start () {
_sensitivity = .4f;
_rotation = Vector3.zero;
}
private void Update()
{
if (_isRotating)
{
foreach (Touch touch in Input.touches)
{
_inputOff = (touch.position - _inputRef);
}
_rotation.y = _inputOff.x * _sensitivity;
_rotation.x = -(_inputOff.y) * _sensitivity;
transform.eulerAngles += _rotation;
}
}
void OnTouchDown(Vector2 point)
{
_isRotating = true;
_inputRef = new Vector2(point.x, point.y);
}
void OnTouchUp()
{
_isRotating = false;
}
void OnTouchStay(Vector2 point)
{
_isRotating = true;
_inputRef = new Vector2(point.x, point.y);
}
void OnTouchExit()
{
_isRotating = false;
}
}
I’m not getting any errors, but the code is also not working at all and I have no idea where to start diagnosing. I’m also probably going about this entirely in the wrong way. Again, what I am attempting to do:
-
The player should be able to drag to
move the camera around the globe. -
The player should be able to also tap
on continents to interact with them. -
These two interactions will not
interfere with each other. -
The camera won’t “snag” at
the north and south poles.