我们有unity做一个简单的游戏--unity切水果,很简单,下面我们看过程。

主要功能就是,有一个苹果放在场景中,然后通过手滑过苹果,就将苹果切成两半,从原理上分析,就是制作两张贴图,分别表示分开的两半苹果,然后在当前位置出现,并且给这两半苹果加上刚体属性,然后分别给这两半苹果加上一个相反的力使其自由落体!

效果图

unity切水果

实现步骤

1.原理分析

就是通过摄像机发出一条射线碰撞到具备碰撞器的苹果,也就是说要给苹果添加上BoxCollider属性,然后苹果检测到碰撞,然后在当前位置出现两个具有刚体(物理)属性的半边苹果,方向是随机出现,然后随机给添加上向量力,使得这两个半个苹果做自由下落。

2.半边苹果的制作

创建一个材质球,然后给材质球赋予贴图属性,就像下图所示的红色区域的图片

                               unity切水果

然后添加上BoxCollider和Rigidbody两个属性,勾选下图所示的红色区域中的选项

                              unity切水果

IsTrigger:勾选上的时候,触发器不会碰撞刚体,但当刚体退出或进入触发器的时候,将会发送OnTriggerEnter,OnTriggerExit和OnTriggerStay消息。
UseGravity:字面解释就是使用重力
Constraints:是约定冻结旋转和移动,这里冻结了Z轴的移动,也就是不允许苹果前后位置的移动,冻结了X,Y轴方向的旋转,也就是不能让苹果前后翻转或者左右旋转。
然后将这半个苹果做成prefeb,删除掉场景中的半个苹果的GameObject。

3.完整苹果的属性的设置

                      unity切水果

主要是让这个主苹果具备BoxCollider属性,使其能够让射线碰撞到,主要要加上AudioSource不然会报错。

4.源代码

该两个代码附加在Apple00上,也就是主苹果上。
knifeRay01    //如果射线碰撞到苹果,就显示出两半苹果,并且给添加两个方向相反的方向力
  1. using UnityEngine;
  2. using System.Collections;
  3. public class knifeRay01 : MonoBehaviour
  4. {
  5. //选择颜色
  6. //    public Color mycolor;
  7. public GameObject myRay;  //这个是刀光的prefab
  8. public AudioClip knifeSound;
  9. public bool isHit = false;
  10. public Vector3 rayPosition;
  11. public bool isRay = false;
  12. public GameObject firstFruit;
  13. public GameObject secondFruit;
  14. private GameObject myFirstFruit;
  15. private GameObject mySecondFruit;
  16. private Vector3 firstPosition;
  17. private Vector3 secondPosition;
  18. // private Vector3 middlePosition;
  19. private bool isClicked = false;
  20. private LineRenderer lineRenderer;
  21. private GameObject rayGameObject;
  22. private float angle;
  23. // Use this for initialization
  24. //void Start () {
  25. //        lineRenderer = gameObject.AddComponent<LineRenderer>();//添加一个划线的组件
  26. //        //设置颜色和宽度
  27. //        lineRenderer.material.color = mycolor;
  28. //        lineRenderer.SetWidth(0.1f, 0.1f);
  29. //}
  30. // Update is called once per frame
  31. void Update()
  32. {
  33. bool isMouseDown = Input.GetMouseButton(0);//判断鼠标是否左击
  34. if (isHit)
  35. {
  36. if (isMouseDown && !isClicked)
  37. {
  38. //屏幕坐标转化成空间坐标
  39. firstPosition = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1));
  40. //            lineRenderer.SetVertexCount(1);
  41. //
  42. //            lineRenderer.enabled = true;
  43. //            lineRenderer.SetPosition(0,firstPosition);
  44. isClicked = true;
  45. }
  46. else if (isMouseDown)
  47. {
  48. secondPosition = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1));
  49. //            lineRenderer.SetVertexCount(2);
  50. //
  51. //            lineRenderer.SetPosition(1, secondPosition);
  52. }
  53. //鼠标提起
  54. else if (Input.GetMouseButtonUp(0))
  55. {
  56. isRay = true;
  57. secondPosition = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1));
  58. if (secondPosition.x != firstPosition.x)
  59. {
  60. angle = Mathf.Atan((secondPosition.y - firstPosition.y) / (secondPosition.x - firstPosition.x));
  61. print("角度:" + angle * 180 / Mathf.PI);
  62. }
  63. else
  64. {
  65. angle = 0;
  66. }
  67. //创建划痕,这里旋转的是幅度
  68. rayGameObject = Instantiate(myRay, rayPosition, Quaternion.AngleAxis(angle * 180 / Mathf.PI, Vector3.forward)) as GameObject;
  69. //两个被切的水果
  70. myFirstFruit = Instantiate(firstFruit, transform.position, Quaternion.AngleAxis(Random.Range(50, 180) * 180 / Mathf.PI, Vector3.forward)) as GameObject;
  71. mySecondFruit = Instantiate(firstFruit, transform.position, Quaternion.AngleAxis(Random.Range(80, 150) * 180 / Mathf.PI, Vector3.forward)) as GameObject;
  72. //myFirstFruit.rigidbody.velocity = new Vector2(Mathf.Sin(angle)*10,-Mathf.Cos(angle)*10);
  73. //mySecondFruit.rigidbody.velocity = new Vector2(Mathf.Sin(angle)*10,Mathf.Cos(angle)*10);
  74. //这里方向是随机出现的,其实正确的应该是计算切线的角度来计算苹果切开两半的一个飞溅的方向
  75. if (Random.Range(1, 10) > 5)
  76. {//给加一个力,方向相反
  77. myFirstFruit.rigidbody.velocity = new Vector2(5, 10);
  78. mySecondFruit.rigidbody.velocity = new Vector2(-8, -10);
  79. myFirstFruit.rigidbody.velocity = new Vector2(0, 10);
  80. mySecondFruit.rigidbody.velocity = new Vector2(0, -10);
  81. }
  82. else
  83. {
  84. myFirstFruit.rigidbody.velocity = new Vector2(-5, 10);
  85. mySecondFruit.rigidbody.velocity = new Vector2(8, -10);
  86. }
  87. Physics.gravity = new Vector3(0, -20, 0);
  88. Destroy(myFirstFruit, 2.0f);
  89. Destroy(mySecondFruit, 2.0f);
  90. if (audio.isPlaying)
  91. {
  92. audio.Stop();
  93. }
  94. else
  95. {
  96. PlaySound(knifeSound);
  97. print("播放声音");
  98. }
  99. Destroy(rayGameObject, 0.2f);//立马释放刀光
  100. //            lineRenderer.SetVertexCount(2);
  101. //
  102. //            lineRenderer.SetPosition(1, secondPosition);
  103. isClicked = false;
  104. isHit = false;
  105. //middlePosition = (firstPosition+secondPosition)/2;
  106. Destroy(rayGameObject, 1.0f);//一秒钟就去掉
  107. }
  108. }
  109. else
  110. {
  111. isRay = false;
  112. }
  113. }
  114. void PlaySound(AudioClip soundName)
  115. {
  116. if (!audio.isPlaying)
  117. {
  118. AudioSource.PlayClipAtPoint(soundName, new Vector3(0, 0, -10));//在指定位置播放
  119. }
  120. }
  121. }
  122. hitByKnife//用于判断射线是否碰撞到苹果
  123. using UnityEngine;
  124. using System.Collections;
  125. public class hitByKnife : MonoBehaviour
  126. {
  127. private bool isClicked = false;
  128. // Use this for initialization
  129. void Start()
  130. {
  131. }
  132. // Update is called once per frame
  133. void Update()
  134. {
  135. bool isMouseDown = Input.GetMouseButton(0);//判断鼠标是否左击
  136. if (!isClicked)
  137. {
  138. if (isMouseDown)
  139. {
  140. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  141. RaycastHit hit;
  142. if (collider.Raycast(ray, out hit, 1000f))
  143. {
  144. transform.GetComponent<knifeRay01>().isHit = true;
  145. transform.GetComponent<knifeRay01>().rayPosition = hit.transform.position;
  146. }
  147. }
  148. }
  149. }
  150. }