We now have a great-looking ice ball just in front of our walking monster. Time to get that ball in motion using the following steps to add the objects and scripts:
DualTouchControls
prefab from the Assets/Standard Assets/CrossPlatformInput/Prefabs
folder in the Project window to the Hierarchy window.DualTouchControls
object to Catch_UI
in the Inspector window.Catch_UI
object and delete the TurnAndLookTouchpad
and the Jump
objects. When prompted to break the prefab, click on continue.MoveTouchpad
object and delete the Text
object by selecting it and pressing delete.MoveTouchpad
object and rename it ThrowTouchpad
in the Inspector window.#FFFFFF00
in Hex.CatchBall
object and drop it onto the empty Throw Object field in Throw Touch Pad component, as shown in the following screenshot:
Configuration for the ThrowTouchpad object
Catch_UI
object onto the CatchScene
object in order to add it as a child.All of the work of throwing the ball is being done by the ThrowTouchPad
script, which uses a heavily modified Touchpad script at its base. Let's review the critical sections of code:
ThrowTouchPad
script in the editor of your choice. Of course, you know how to do this now.if
statement that checks whether a throwObject
is not null. Further initialization of variables is down in the ResetTarget()
call. The following is the code for review:if (throwObject != null) { startPosition = throwObject.transform.position; startRotation = throwObject.transform.rotation; throwObject.SetActive(false); ResetTarget(); }
OnPointerDown
method; the code for the method is shown here for review:public void OnPointerDown(PointerEventData data) { Ray ray = Camera.main.ScreenPointToRay(data.position); RaycastHit hit; if (Physics.Raycast(ray, out hit, 100f)) { //check if target object was hit if (hit.transform == target.transform) { //yes, start dragging the object m_Dragging = true; m_Id = data.pointerId; screenPosition = Camera.main.WorldToScreenPoint (target.transform.position); offset = target.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(data.position.x, data.position.y, screenPosition.z)); } } }
Physics.RayCast
method is used, without a layer mask. If the pointer (touch) hits something, it checks whether it is the target, which so happens to be the CatchBall
. If it has hit the target, then it sets a Boolean m_Dragging
to true and gets a screen position of the touched object and of the offset of the pointer or touch.Update
method, you will see an if
statement that checks whether the ball is being dragged by checking the m_Dragging Boolean
. If it is, then it takes a snapshot of the current pointer (touch) position and calls the OnDragging
method for review:void OnDragging(Vector3 touchPos) { //track mouse position. Vector3 currentScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPosition.z); //convert screen position to world position with offset changes. Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenSpace) + offset; //It will update target gameobject's current postion. target.transform.position = currentPosition; }
OnDragging
method just moves the target object (ball) around the screen based on the pointer (touch) position.OnPointerUp
method. The OnPointerUp
method is called when the mouse button is released or a touch is removed. The code inside the method is quite simple: it again checks whether the m_Dragging
is true; if it isn't, it just returns. If an object is being dragged, then at this point, the ThrowObject
method is called, as shown in the following code:void ThrowObject(Vector2 pos) { rb.useGravity = true; //turn on gravity float y = (pos.y - lastPos.y) / Screen.height * 100; speed = throwSpeed * y; float x = (pos.x / Screen.width) - (lastPos.x / Screen.width); x = Mathf.Abs(pos.x - lastPos.x) / Screen.width * 100 * x; Vector3 direction = new Vector3(x, 0f, 1f); direction = Camera.main.transform.TransformDirection(direction); rb.AddForce((direction * speed * 2f ) + (Vector3.up * speed/2f)); thrown = true; var ca = target.GetComponent<CollisionAction>(); if(ca != null) { ca.disarmmed = false; } Invoke("ResetTarget", 5); }
ThrowObject
method is where we calculate the launch position and determine the force with which the object will be thrown. The x,y
calculations determine how fast the object was moving across the screen before it was released. It determines this by taking the difference between the last-known pointer position and the position of the release. The x value or position of release determines the direction (left or right) of the throw, whereas the y or up movement determines the speed of the throw. These values are then summed into a force vector and applied to the rigidbody by the call rb.AddForce()
. The rb
is the target rigidbody, which was set in the ResetTarget
method during initialization. At the bottom of the method is the call to GetComponent
for a CollisionAction
component. We won't worry about this here, but will cover it later. Then, finally, we call ResetTarget
again using the Invoke
method, which waits for 5 seconds before being called.
Rigidbody.AddForce
is one of the most important methods to master when developing any game with physics. You can find more excellent physics resources at https://unity3d.com/learn/tutorials/topics/physics.
3.129.70.157