1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// 摄像机跟随玩家
  5. /// </summary>
  6. public class CameraFollow : MonoBehaviour
  7. {
  8. /// <summary>
  9. /// 目标
  10. /// </summary>
  11. public Transform target;
  12. /// <summary>
  13. /// 和目标之间的偏移
  14. /// </summary>
  15. );
  16. /// <summary>
  17. /// 是否锁定旋转
  18. /// </summary>
  19. public bool lockRotation;
  20. /// <summary>
  21. /// 跟随速度
  22. /// </summary>
  23. ;
  24. /// <summary>
  25. /// 围绕目标旋转的速度
  26. /// </summary>
  27. ;
  28. /// <summary>
  29. /// 是否可以由鼠标控制旋转(只有在相机没有被固定的情况下)
  30. /// </summary>
  31. public bool mouseFreelook;
  32. /// <summary>
  33. /// 旋转阻尼
  34. /// </summary>
  35. ;
  36. /// <summary>
  37. /// 摄像机在水中时的过滤物体
  38. /// </summary>
  39. public GameObject waterFilter;
  40. /// <summary>
  41. ///
  42. /// </summary>
  43. public string[] avoidClippingTags;
  44.  
  45. /// <summary>
  46. /// Camera Target
  47. /// </summary>
  48. private Transform followTarget;
  49. /// <summary>
  50. /// 暂未用到
  51. /// </summary>
  52. private bool camColliding;
  53.  
  54. //setup objects
  55. void Awake()
  56. {
  57. //创建跟随物体(Camera Target)
  58. followTarget = new GameObject().transform;
  59. followTarget.name = "Camera Target";
  60. if(waterFilter)
  61. waterFilter.GetComponent<Renderer>().enabled = false;
  62. if(!target)
  63. Debug.LogError("'CameraFollow script' has no target assigned to it", transform);
  64.  
  65. //如果用鼠标控制旋转,旋转阻尼为0
  66. if(mouseFreelook)
  67. rotateDamping = 0f;
  68. }
  69.  
  70. void Update()
  71. {
  72. //没有目标不处理
  73. if (!target)
  74. return;
  75. //平滑跟随
  76. SmoothFollow ();
  77. //平滑朝向玩家
  78. )
  79. SmoothLookAt();
  80. //直接朝向玩家
  81. else
  82. transform.LookAt(target.position);
  83. }
  84.  
  85. void OnTriggerEnter(Collider other)
  86. {
  87. //打开水遮罩
  88. if (other.tag == "Water" && waterFilter)
  89. waterFilter.GetComponent<Renderer>().enabled = true;
  90. }
  91.  
  92. void OnTriggerExit(Collider other)
  93. {
  94. //关闭水遮罩
  95. if (other.tag == "Water" && waterFilter)
  96. waterFilter.GetComponent<Renderer>().enabled = false;
  97. }
  98.  
  99. /// <summary>
  100. /// 平滑朝向目标
  101. /// </summary>
  102. void SmoothLookAt()
  103. {
  104. Quaternion rotation = Quaternion.LookRotation (target.position - transform.position);
  105. transform.rotation = Quaternion.Slerp (transform.rotation, rotation, rotateDamping * Time.deltaTime);
  106. }
  107.  
  108. /// <summary>
  109. /// 平滑跟随目标
  110. /// </summary>
  111. void SmoothFollow()
  112. {
  113. followTarget.position = target.position;
  114. followTarget.Translate(targetOffset, Space.Self);
  115. if (lockRotation)
  116. followTarget.rotation = target.rotation;
  117.  
  118. //鼠标控制围绕目标旋转
  119. if(mouseFreelook)
  120. {
  121. float axisX = Input.GetAxis ("Mouse X") * inputRotationSpeed * Time.deltaTime;
  122. followTarget.RotateAround (target.position,Vector3.up, axisX);
  123. float axisY = Input.GetAxis ("Mouse Y") * inputRotationSpeed * Time.deltaTime;
  124. followTarget.RotateAround (target.position, transform.right, -axisY);
  125. }
  126. //键盘控制围绕目标旋转
  127. else
  128. {
  129. float axis = Input.GetAxis ("CamHorizontal") * inputRotationSpeed * Time.deltaTime;
  130. followTarget.RotateAround (target.position, Vector3.up, axis);
  131. }
  132.  
  133. //计算相机的下一帧位置
  134. Vector3 nextFramePosition = Vector3.Lerp(transform.position, followTarget.position, followSpeed * Time.deltaTime);
  135. Vector3 direction = nextFramePosition - target.position;
  136. //射线检测这个位置
  137. RaycastHit hit;
  138. if(Physics.Raycast (target.position, direction, out hit, direction.magnitude + 0.3f))
  139. {
  140. transform.position = nextFramePosition;
  141. foreach(string tag in avoidClippingTags)
  142. //如果这个位置有物体,修改相机位置
  143. if(hit.transform.tag == tag)
  144. transform.position = hit.point - direction.normalized * 0.3f;
  145. }
  146. else
  147. {
  148. //直接修改相机位置
  149. transform.position = nextFramePosition;
  150. }
  151. }
  152. }

CameraFollow

  1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// 角色移动
  5. /// </summary>
  6. [RequireComponent(typeof(Rigidbody))]
  7. public class CharacterMotor:MonoBehaviour {
  8. /// <summary>
  9. /// 是否冻结z轴的移动
  10. /// </summary>
  11. public bool sidescroller;
  12. /// <summary>
  13. /// 当前速度
  14. /// </summary>
  15. [HideInInspector]
  16. public Vector3 currentSpeed;
  17. /// <summary>
  18. /// 到目标的距离
  19. /// </summary>
  20. [HideInInspector]
  21. public float DistanceToTarget;
  22. /// <summary>
  23. /// 刚体
  24. /// </summary>
  25. private Rigidbody rigid;
  26.  
  27. void Awake() {
  28. //设置rigidbody
  29. rigid = GetComponent<Rigidbody>();
  30. rigid.interpolation = RigidbodyInterpolation.Interpolate;
  31. if(sidescroller)
  32. rigid.constraints = RigidbodyConstraints.FreezeRotation | RigidbodyConstraints.FreezePositionZ;
  33. else
  34. rigid.constraints = RigidbodyConstraints.FreezeRotation;
  35. //添加光滑的物理材质
  36. if(GetComponent<Collider>().material.name == "Default (Instance)") {
  37. PhysicMaterial pMat = new PhysicMaterial();
  38. pMat.name = "Frictionless";
  39. pMat.frictionCombine = PhysicMaterialCombine.Multiply;
  40. pMat.bounceCombine = PhysicMaterialCombine.Multiply;
  41. pMat.dynamicFriction = 0f;
  42. pMat.staticFriction = 0f;
  43. GetComponent<Collider>().material = pMat;
  44. Debug.LogWarning("No physics material found for CharacterMotor, a frictionless one has been created and assigned",transform);
  45. }
  46. }
  47.  
  48. /// <summary>
  49. /// 移动刚体到指定位置
  50. /// </summary>
  51. public bool MoveTo(Vector3 destination,float acceleration,float stopDistance,bool ignoreY) {
  52. Vector3 relativePos = (destination - transform.position);
  53. //忽略y轴?
  54. if(ignoreY)
  55. relativePos.y = ;
  56.  
  57. DistanceToTarget = relativePos.magnitude;
  58. if(DistanceToTarget <= stopDistance)
  59. return true;
  60. else
  61. rigid.AddForce(relativePos.normalized * acceleration * Time.deltaTime,ForceMode.VelocityChange);
  62. return false;
  63. }
  64.  
  65. /// <summary>
  66. /// 旋转刚体朝向当前速度
  67. /// </summary>
  68. public void RotateToVelocity(float turnSpeed,bool ignoreY) {
  69. Vector3 dir;
  70. if(ignoreY)
  71. dir = new Vector3(rigid.velocity.x,0f,rigid.velocity.z);
  72. else
  73. dir = rigid.velocity;
  74.  
  75. if(dir.magnitude > 0.1) {
  76. Quaternion dirQ = Quaternion.LookRotation(dir);
  77. Quaternion slerp = Quaternion.Slerp(transform.rotation,dirQ,dir.magnitude * turnSpeed * Time.deltaTime);
  78. rigid.MoveRotation(slerp);
  79. }
  80. }
  81.  
  82. /// <summary>
  83. /// 旋转刚体朝向指定方向
  84. /// </summary>
  85. public void RotateToDirection(Vector3 lookDir,float turnSpeed,bool ignoreY) {
  86. Vector3 characterPos = transform.position;
  87. //忽略y轴?
  88. if(ignoreY) {
  89. characterPos.y = ;
  90. lookDir.y = ;
  91. }
  92.  
  93. Vector3 newDir = lookDir - characterPos;
  94. Quaternion dirQ = Quaternion.LookRotation(newDir);
  95. Quaternion slerp = Quaternion.Slerp(transform.rotation,dirQ,turnSpeed * Time.deltaTime);
  96. rigid.MoveRotation(slerp);
  97. }
  98.  
  99. /// <summary>
  100. /// 管理速度
  101. /// </summary>
  102. public void ManageSpeed(float deceleration,float maxSpeed,bool ignoreY) {
  103. currentSpeed = rigid.velocity;
  104. //忽略y轴
  105. if(ignoreY)
  106. currentSpeed.y = ;
  107.  
  108. ) {
  109. rigid.AddForce((currentSpeed * -) * deceleration * Time.deltaTime,ForceMode.VelocityChange);
  110. if(rigid.velocity.magnitude > maxSpeed)
  111. rigid.AddForce((currentSpeed * -) * deceleration * Time.deltaTime,ForceMode.VelocityChange);
  112. }
  113. }
  114. }

CharacterMotor

  1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// 检查点
  5. /// </summary>
  6. [RequireComponent(typeof(CapsuleCollider))]
  7. [RequireComponent(typeof(AudioSource))]
  8. public class Checkpoint : MonoBehaviour
  9. {
  10. /// <summary>
  11. /// 激活颜色
  12. /// </summary>
  13. public Color activeColor = Color.green;
  14. /// <summary>
  15. /// 激活时的不透明度
  16. /// </summary>
  17. public float activeColorOpacity = 0.4f;
  18.  
  19. /// <summary>
  20. /// 生命
  21. /// </summary>
  22. private Health health;
  23. /// <summary>
  24. /// 默认颜色
  25. /// </summary>
  26. private Color defColor;
  27. /// <summary>
  28. /// 检查点列表
  29. /// </summary>
  30. private GameObject[] checkpoints;
  31. /// <summary>
  32. /// 渲染器
  33. /// </summary>
  34. private Renderer render;
  35. /// <summary>
  36. /// AudioSource
  37. /// </summary>
  38. private AudioSource aSource;
  39.  
  40. void Awake()
  41. {
  42. render = GetComponent<Renderer>();
  43. aSource = GetComponent<AudioSource>();
  44. //标签不是Respawn,自动修改标签
  45. if(tag != "Respawn")
  46. {
  47. tag = "Respawn";
  48. Debug.LogWarning ("'Checkpoint' script attached to object without the 'Respawn' tag, tag has been assigned automatically", transform);
  49. }
  50. GetComponent<Collider>().isTrigger = true;
  51. //设置默认颜色和不透明度
  52. if(render)
  53. defColor = render.material.color;
  54. activeColor.a = activeColorOpacity;
  55. }
  56.  
  57. void Start()
  58. {
  59. checkpoints = GameObject.FindGameObjectsWithTag("Respawn");
  60. health = GameObject.FindGameObjectWithTag("Player").GetComponent<Health>();
  61. if(!health)
  62. Debug.LogError("For Checkpoint to work, the Player needs 'Health' script attached", transform);
  63. }
  64.  
  65. void OnTriggerEnter(Collider other)
  66. {
  67. //如果碰到玩家
  68. if(other.transform.tag == "Player" && health)
  69. {
  70. health.respawnPos = transform.position;
  71.  
  72. if(render.material.color != activeColor)
  73. {
  74. foreach (GameObject checkpoint in checkpoints)
  75. checkpoint.GetComponent<Renderer>().material.color = defColor;
  76. aSource.Play();
  77. render.material.color = activeColor;
  78. }
  79. }
  80. }
  81. }

Checkpoint

  1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// 金币
  5. /// </summary>
  6. [RequireComponent(typeof(SphereCollider))]
  7. public class Coin : MonoBehaviour
  8. {
  9. /// <summary>
  10. /// 被收集时的声音
  11. /// </summary>
  12. public AudioClip collectSound;
  13. /// <summary>
  14. /// 旋转
  15. /// </summary>
  16. , , );
  17. /// <summary>
  18. /// 玩家靠近时,增加的旋转
  19. /// </summary>
  20. , , );
  21. /// <summary>
  22. /// 金币向玩家移动的速度
  23. /// </summary>
  24. public float startSpeed = 3f;
  25. /// <summary>
  26. /// 金币向玩家移动的加速度
  27. /// </summary>
  28. public float speedGain = 0.2f;
  29.  
  30. /// <summary>
  31. /// 是否被搜集
  32. /// </summary>
  33. private bool collected;
  34. /// <summary>
  35. /// 玩家
  36. /// </summary>
  37. private Transform player;
  38. /// <summary>
  39. /// 子物体的触发器
  40. /// </summary>
  41. private TriggerParent triggerParent;
  42. /// <summary>
  43. /// GUI
  44. /// </summary>
  45. private GUIManager gui;
  46.  
  47. void Awake()
  48. {
  49. gui = FindObjectOfType(typeof(GUIManager)) as GUIManager ;
  50. if(tag != "Coin")
  51. {
  52. tag = "Coin";
  53. Debug.LogWarning ("'Coin' script attached to object not tagged 'Coin', tag added automatically", transform);
  54. }
  55. GetComponent<Collider>().isTrigger = true;
  56. triggerParent = GetComponentInChildren<TriggerParent>();
  57. //添加bounds子物体
  58. if(!triggerParent)
  59. {
  60. GameObject bounds = new GameObject();
  61. bounds.name = "Bounds";
  62. bounds.AddComponent<SphereCollider>();
  63. bounds.GetComponent<SphereCollider>().radius = 7f;
  64. bounds.GetComponent<SphereCollider>().isTrigger = true;
  65. bounds.transform.parent = transform;
  66. bounds.transform.position = transform.position;
  67. bounds.AddComponent<TriggerParent>();
  68. triggerParent = GetComponentInChildren<TriggerParent>();
  69. triggerParent.tagsToCheck = ];
  70. triggerParent.tagsToCheck[] = "Player";
  71. Debug.LogWarning ("No pickup radius 'bounds' trigger attached to coin: " + transform.name + ", one has been added automatically", bounds);
  72. }
  73. }
  74.  
  75. void Start()
  76. {
  77. player = GameObject.FindGameObjectWithTag("Player").transform;
  78. }
  79.  
  80. void Update()
  81. {
  82.  
  83. transform.Rotate (rotation * Time.deltaTime, Space.World);
  84.  
  85. if(triggerParent.collided)
  86. collected = true;
  87.  
  88. //增加金币的旋转速度和移动速度,将金币移向玩家
  89. if (collected)
  90. {
  91. startSpeed += speedGain;
  92. rotation += rotationGain;
  93. transform.position = Vector3.Lerp (transform.position, player.position, startSpeed * Time.deltaTime);
  94. }
  95. }
  96.  
  97. void OnTriggerEnter(Collider other)
  98. {
  99. if (other.tag == "Player")
  100. CoinGet();
  101. }
  102.  
  103. /// <summary>
  104. /// 获取金币
  105. /// </summary>
  106. void CoinGet()
  107. {
  108. if(collectSound)
  109. AudioSource.PlayClipAtPoint(collectSound, transform.position);
  110. if (gui)
  111. gui.coinsCollected ++;
  112. Destroy(gameObject);
  113. }
  114. }

Coin

  1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// 处理伤害
  5. /// </summary>
  6. public class DealDamage : MonoBehaviour
  7. {
  8. /// <summary>
  9. /// 受害人的生命
  10. /// </summary>
  11. private Health health;
  12.  
  13. /// <summary>
  14. /// 攻击
  15. /// </summary>
  16. public void Attack(GameObject victim, int dmg, float pushHeight, float pushForce)
  17. {
  18. health = victim.GetComponent<Health>();
  19.  
  20. //推物体
  21. Vector3 pushDir = (victim.transform.position - transform.position);
  22. pushDir.y = 0f;
  23. pushDir.y = pushHeight * 0.1f;
  24. if (victim.GetComponent<Rigidbody>() && !victim.GetComponent<Rigidbody>().isKinematic)
  25. {
  26. victim.GetComponent<Rigidbody>().velocity = , , );
  27. victim.GetComponent<Rigidbody>().AddForce (pushDir.normalized * pushForce, ForceMode.VelocityChange);
  28. victim.GetComponent<Rigidbody>().AddForce (Vector3.up * pushHeight, ForceMode.VelocityChange);
  29. }
  30. //应用伤害
  31. if(health && !health.flashing)
  32. health.currentHealth -= dmg;
  33. }
  34. }

DealDamage

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// 摧毁物体
  6. /// </summary>
  7. public class DestroyObject : MonoBehaviour
  8. {
  9. /// <summary>
  10. /// 摧毁声音
  11. /// </summary>
  12. public AudioClip destroySound;
  13. /// <summary>
  14. /// 延迟
  15. /// </summary>
  16. public float delay;
  17. /// <summary>
  18. /// 是否分离子物体并且不摧毁子物体
  19. /// </summary>
  20. public bool destroyChildren;
  21. /// <summary>
  22. /// 从父物体中心推开子物体的数量
  23. /// </summary>
  24. public float pushChildAmount;
  25.  
  26. void Start()
  27. {
  28. //获取子物体列表
  29. Transform[] children = new Transform[transform.childCount];
  30. ; i < transform.childCount; i++)
  31. children[i] = transform.GetChild(i);
  32.  
  33. //分离子物体
  34. if (!destroyChildren)
  35. transform.DetachChildren();
  36.  
  37. //给子物体添加一个推力和旋转
  38. foreach (Transform child in children)
  39. {
  40. Rigidbody rigid = child.GetComponent<Rigidbody>();
  41. )
  42. {
  43. Vector3 pushDir = child.position - transform.position;
  44. rigid.AddForce(pushDir * pushChildAmount, ForceMode.Force);
  45. rigid.AddTorque(Random.insideUnitSphere, ForceMode.Force);
  46. }
  47. }
  48.  
  49. //删除父物体
  50. if(destroySound)
  51. AudioSource.PlayClipAtPoint(destroySound, transform.position);
  52. Destroy (gameObject, delay);
  53. }
  54. }

DestroyObject

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// 敌人AI
  6. /// </summary>
  7. [RequireComponent(typeof(CharacterMotor))]
  8. [RequireComponent(typeof(DealDamage))]
  9. public class EnemyAI : MonoBehaviour
  10. {
  11. /// <summary>
  12. /// 移动加速度
  13. /// </summary>
  14. public float acceleration = 35f;
  15. /// <summary>
  16. /// 移动减速度
  17. /// </summary>
  18. public float deceleration = 8f;
  19. /// <summary>
  20. /// 旋转速度
  21. /// </summary>
  22. public float rotateSpeed = 0.7f;
  23. /// <summary>
  24. /// 速度极限
  25. /// </summary>
  26. public float speedLimit = 10f;
  27. /// <summary>
  28. /// 玩家跳到敌人头上时应用到玩家身上的力
  29. /// </summary>
  30. , , );
  31. /// <summary>
  32. /// 玩家跳到敌人头上时的声音
  33. /// </summary>
  34. public AudioClip bounceSound;
  35. /// <summary>
  36. /// 玩家碰到敌人时受到的推力
  37. /// </summary>
  38. public float pushForce = 10f;
  39. /// <summary>
  40. /// 玩家碰到敌人时玩家的高度
  41. /// </summary>
  42. public float pushHeight = 7f;
  43. /// <summary>
  44. /// 敌人对玩家的伤害
  45. /// </summary>
  46. ;
  47. /// <summary>
  48. /// 是否追逐视野内的目标
  49. /// </summary>
  50. public bool chase = true;
  51. /// <summary>
  52. /// 追逐时是否忽略y轴
  53. /// </summary>
  54. public bool ignoreY = true;
  55. /// <summary>
  56. /// 追逐停止的距离
  57. /// </summary>
  58. public float chaseStopDistance = 0.7f;
  59. /// <summary>
  60. /// 视野范围
  61. /// </summary>
  62. public GameObject sightBounds;
  63. /// <summary>
  64. /// 攻击范围
  65. /// </summary>
  66. public GameObject attackBounds;
  67. /// <summary>
  68. /// Animator
  69. /// </summary>
  70. public Animator animatorController;
  71. /// <summary>
  72. /// 移动到路标点
  73. /// </summary>
  74. public MoveToPoints moveToPointsScript;
  75.  
  76. /// <summary>
  77. /// 视野触发器
  78. /// </summary>
  79. private TriggerParent sightTrigger;
  80. /// <summary>
  81. /// 攻击触发器
  82. /// </summary>
  83. private TriggerParent attackTrigger;
  84. /// <summary>
  85. /// 玩家移动
  86. /// </summary>
  87. private PlayerMove playerMove;
  88. /// <summary>
  89. /// 角色移动
  90. /// </summary>
  91. private CharacterMotor characterMotor;
  92. /// <summary>
  93. /// 处理伤害
  94. /// </summary>
  95. private DealDamage dealDamage;
  96.  
  97. void Awake()
  98. {
  99. characterMotor = GetComponent<CharacterMotor>();
  100. dealDamage = GetComponent<DealDamage>();
  101. if(tag != "Enemy")
  102. {
  103. tag = "Enemy";
  104. Debug.LogWarning("'EnemyAI' script attached to object without 'Enemy' tag, it has been assign automatically", transform);
  105. }
  106.  
  107. if(sightBounds)
  108. {
  109. sightTrigger = sightBounds.GetComponent<TriggerParent>();
  110. if(!sightTrigger)
  111. Debug.LogError("'TriggerParent' script needs attaching to enemy 'SightBounds'", sightBounds);
  112. }
  113. if(!sightBounds)
  114. Debug.LogWarning("Assign a trigger with 'TriggerParent' script attached, to 'SightBounds' or enemy will not be able to see", transform);
  115.  
  116. if(attackBounds)
  117. {
  118. attackTrigger = attackBounds.GetComponent<TriggerParent>();
  119. if(!attackTrigger)
  120. Debug.LogError("'TriggerParent' script needs attaching to enemy 'attackBounds'", attackBounds);
  121. }
  122. else
  123. Debug.LogWarning("Assign a trigger with 'TriggerParent' script attached, to 'AttackBounds' or enemy will not be able to attack", transform);
  124. }
  125.  
  126. void Update()
  127. {
  128. //追逐
  129. if (sightTrigger && sightTrigger.colliding && chase && sightTrigger.hitObject != null && sightTrigger.hitObject.activeInHierarchy)
  130. {
  131. characterMotor.MoveTo (sightTrigger.hitObject.transform.position, acceleration, chaseStopDistance, ignoreY);
  132.  
  133. if(animatorController)
  134. animatorController.SetBool("Moving", true);
  135.  
  136. if(moveToPointsScript)
  137. moveToPointsScript.enabled = false;
  138. }
  139. else
  140. {
  141.  
  142. if(animatorController)
  143. animatorController.SetBool("Moving", false);
  144.  
  145. if(moveToPointsScript)
  146. moveToPointsScript.enabled = true;
  147. }
  148.  
  149. //攻击
  150. if (attackTrigger && attackTrigger.collided)
  151. {
  152. dealDamage.Attack(attackTrigger.hitObject, attackDmg, pushHeight, pushForce);
  153.  
  154. if(animatorController)
  155. animatorController.SetBool("Attacking", true);
  156. }
  157. else if(animatorController)
  158. animatorController.SetBool("Attacking", false);
  159. }
  160.  
  161. void FixedUpdate()
  162. {
  163. characterMotor.ManageSpeed(deceleration, speedLimit, ignoreY);
  164. characterMotor.RotateToVelocity (rotateSpeed, ignoreY);
  165. }
  166.  
  167. /// <summary>
  168. /// 弹开玩家
  169. /// </summary>
  170. public void BouncedOn()
  171. {
  172. if(!playerMove)
  173. playerMove = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerMove>();
  174. if (bounceSound)
  175. AudioSource.PlayClipAtPoint(bounceSound, transform.position);
  176. if(playerMove)
  177. {
  178. Vector3 bounceMultiplier = new Vector3(0f, 1.5f, 0f) * playerMove.onEnemyBounce;
  179. playerMove.Jump (bounceForce + bounceMultiplier);
  180. }
  181. else
  182. Debug.LogWarning("'Player' tagged object landed on enemy, but without playerMove script attached, is unable to bounce");
  183. }
  184. }

EnemyAI

  1. using UnityEngine;
  2.  
  3. /// <summary>
  4. /// 关卡目标
  5. /// </summary>
  6. [RequireComponent(typeof(CapsuleCollider))]
  7. public class Goal : MonoBehaviour
  8. {
  9. /// <summary>
  10. /// 举起玩家的力
  11. /// </summary>
  12. public float lift;
  13. /// <summary>
  14. /// 加载下一个关卡的等待时间
  15. /// </summary>
  16. public float loadDelay;
  17. /// <summary>
  18. /// 下一个场景的索引
  19. /// </summary>
  20. public int nextLevelIndex;
  21.  
  22. /// <summary>
  23. /// 计时器
  24. /// </summary>
  25. private float counter;
  26.  
  27. void Awake()
  28. {
  29. GetComponent<Collider>().isTrigger = true;
  30. }
  31.  
  32. void OnTriggerStay(Collider other)
  33. {
  34. Rigidbody rigid = other.GetComponent<Rigidbody>();
  35. if(rigid)
  36. rigid.AddForce(Vector3.up * lift, ForceMode.Force);
  37.  
  38. if (other.tag == "Player")
  39. {
  40. counter += Time.deltaTime;
  41. if(counter > loadDelay)
  42. Application.LoadLevel (nextLevelIndex);
  43. }
  44. }
  45.  
  46. void OnTriggerExit(Collider other)
  47. {
  48. if (other.tag == "Player")
  49. counter = 0f;
  50. }
  51. }

Goal

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// GUI
  6. /// </summary>
  7. public class GUIManager : MonoBehaviour
  8. {
  9. /// <summary>
  10. /// GUISkin
  11. /// </summary>
  12. public GUISkin guiSkin;
  13. /// <summary>
  14. /// 已收集的金币
  15. /// </summary>
  16. [HideInInspector]
  17. public int coinsCollected;
  18. /// <summary>
  19. /// 场景中的金币数量
  20. /// </summary>
  21. private int coinsInLevel;
  22. /// <summary>
  23. /// 生命
  24. /// </summary>
  25. private Health health;
  26.  
  27. void Start()
  28. {
  29. coinsInLevel = GameObject.FindGameObjectsWithTag("Coin").Length;
  30. health = GameObject.FindGameObjectWithTag("Player").GetComponent<Health>();
  31. }
  32.  
  33. void OnGUI()
  34. {
  35. GUI.skin = guiSkin;
  36. GUILayout.Space(5f);
  37.  
  38. if(health)
  39. GUILayout.Label ("Health: " + health.currentHealth);
  40. )
  41. GUILayout.Label ("Cubes: " + coinsCollected + " / " + coinsInLevel);
  42. }
  43. }

GUIManager

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// 障碍
  6. /// </summary>
  7. [RequireComponent(typeof(DealDamage))]
  8. [RequireComponent(typeof(AudioSource))]
  9. public class Hazard : MonoBehaviour
  10. {
  11. /// <summary>
  12. /// 推开受害者的力
  13. /// </summary>
  14. public float pushForce = 25f;
  15. /// <summary>
  16. /// 向上推的力
  17. /// </summary>
  18. public float pushHeight = 6f;
  19. /// <summary>
  20. /// 照成的伤害
  21. /// </summary>
  22. ;
  23. /// <summary>
  24. /// 是否是触发
  25. /// </summary>
  26. public bool triggerEnter;
  27. /// <summary>
  28. /// 是否是碰撞
  29. /// </summary>
  30. public bool collisionEnter = true;
  31. /// <summary>
  32. /// 影响的单位的标签
  33. /// </summary>
  34. public string[] effectedTags = {"Player"};
  35. /// <summary>
  36. /// 碰撞声音
  37. /// </summary>
  38. public AudioClip hitSound;
  39.  
  40. /// <summary>
  41. /// 处理伤害
  42. /// </summary>
  43. private DealDamage dealDamage;
  44. /// <summary>
  45. /// AudioSource
  46. /// </summary>
  47. private AudioSource aSource;
  48.  
  49. //setup
  50. void Awake()
  51. {
  52. aSource = GetComponent<AudioSource>();
  53. aSource.playOnAwake = false;
  54. dealDamage = GetComponent<DealDamage>();
  55. }
  56.  
  57. void OnCollisionEnter(Collision col)
  58. {
  59. //不是碰撞
  60. if(!collisionEnter)
  61. return;
  62. //遍历检查标签
  63. foreach(string tag in effectedTags)
  64. //标签相等
  65. if(col.transform.tag == tag)
  66. {
  67. //处理伤害
  68. dealDamage.Attack (col.gameObject, damage, pushHeight, pushForce);
  69. //播放声音
  70. if (hitSound)
  71. {
  72. aSource.clip = hitSound;
  73. aSource.Play();
  74. }
  75. }
  76. }
  77.  
  78. void OnTriggerEnter(Collider other)
  79. {
  80. //不是触发器
  81. if(!triggerEnter)
  82. return;
  83. //遍历标签
  84. foreach(string tag in effectedTags)
  85. //标签相等
  86. if(other.transform.tag == tag)
  87. //处理伤害
  88. dealDamage.Attack (other.gameObject, damage, pushHeight, pushForce);
  89. }
  90. }

Hazard

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// 生命
  6. /// </summary>
  7. [RequireComponent(typeof(AudioSource))]
  8. public class Health : MonoBehaviour
  9. {
  10. /// <summary>
  11. /// 撞击声音
  12. /// </summary>
  13. public AudioClip impactSound;
  14. /// <summary>
  15. /// 受到伤害时的声音
  16. /// </summary>
  17. public AudioClip hurtSound;
  18. /// <summary>
  19. /// 死亡声音
  20. /// </summary>
  21. public AudioClip deadSound;
  22. /// <summary>
  23. /// 当前生命
  24. /// </summary>
  25. ;
  26. /// <summary>
  27. /// 是否能受到撞击伤害
  28. /// </summary>
  29. public bool takeImpactDmg;
  30. /// <summary>
  31. /// 是否只能受到刚体伤害
  32. /// </summary>
  33. public bool onlyRigidbodyImpact;
  34. /// <summary>
  35. /// 是否可以重生
  36. /// </summary>
  37. public bool respawn;
  38. /// <summary>
  39. /// 不会受到撞击伤害的标签
  40. /// </summary>
  41. public string[] impactFilterTag;
  42. /// <summary>
  43. /// 受到伤害时的闪烁延迟
  44. /// </summary>
  45. public float hitFlashDelay = 0.1f;
  46. /// <summary>
  47. /// 闪烁持续时间
  48. /// </summary>
  49. public float flashDuration = 0.9f;
  50. /// <summary>
  51. /// 受到伤害时的闪烁颜色
  52. /// </summary>
  53. public Color hitFlashColor = Color.red;
  54. /// <summary>
  55. /// 闪烁的物体
  56. /// </summary>
  57. public Transform flashObject;
  58. /// <summary>
  59. ///
  60. /// </summary>
  61. public GameObject[] spawnOnDeath;
  62.  
  63. /// <summary>
  64. /// 是否死亡,是否闪烁
  65. /// </summary>
  66. [HideInInspector]
  67. public bool dead, flashing;
  68. /// <summary>
  69. /// 重生位置
  70. /// </summary>
  71. [HideInInspector]
  72. public Vector3 respawnPos;
  73.  
  74. /// <summary>
  75. /// 原始颜色
  76. /// </summary>
  77. private Color originalColor;
  78. /// <summary>
  79. ///
  80. /// </summary>
  81. private int defHealth, h, hitForce;
  82. private bool hitColor = false;
  83. /// <summary>
  84. /// 下一个闪烁,停止闪烁时间
  85. /// </summary>
  86. private float nextFlash, stopFlashTime;
  87. /// <summary>
  88. /// 扔物体
  89. /// </summary>
  90. private Throwing throwing;
  91. /// <summary>
  92. /// 闪烁渲染器
  93. /// </summary>
  94. private Renderer flashRender;
  95. /// <summary>
  96. /// AudioSource
  97. /// </summary>
  98. private AudioSource aSource;
  99.  
  100. void Awake()
  101. {
  102. aSource = GetComponent<AudioSource>();
  103. )
  104. Debug.LogWarning(transform.name + " has 'currentHealth' set to 0 or less in 'Health' script: it has died upon scene start");
  105. aSource.playOnAwake = false;
  106. if(flashObject == null)
  107. flashObject = transform;
  108. flashRender = flashObject.GetComponent<Renderer>();
  109. originalColor = flashRender.material.color;
  110. defHealth = currentHealth;
  111. respawnPos = transform.position;
  112. }
  113.  
  114. void Update()
  115. {
  116. //受到伤害,闪烁
  117. if (currentHealth < h)
  118. {
  119. flashing = true;
  120. stopFlashTime = Time.time + flashDuration;
  121. if (hurtSound)
  122. AudioSource.PlayClipAtPoint(hurtSound, transform.position);
  123. }
  124. h = currentHealth;
  125.  
  126. if (flashing)
  127. {
  128. Flash ();
  129. if (Time.time > stopFlashTime)
  130. {
  131. flashRender.material.color = originalColor;
  132. flashing = false;
  133. }
  134. }
  135.  
  136. dead = (currentHealth <= ) ? true : false;
  137. if (dead)
  138. Death();
  139. }
  140.  
  141. /// <summary>
  142. /// 闪烁
  143. /// </summary>
  144. void Flash()
  145. {
  146. flashRender.material.color = (hitColor) ? hitFlashColor : originalColor;
  147. if(Time.time > nextFlash)
  148. {
  149. hitColor = !hitColor;
  150. nextFlash = Time.time + hitFlashDelay;
  151. }
  152. }
  153.  
  154. /// <summary>
  155. /// 死亡
  156. /// </summary>
  157. void Death()
  158. {
  159.  
  160. if(tag == "Player")
  161. throwing = GetComponent<Throwing>();
  162. if(throwing && throwing.heldObj && throwing.heldObj.tag == "Pickup")
  163. throwing.ThrowPickup();
  164.  
  165. if (deadSound)
  166. AudioSource.PlayClipAtPoint(deadSound, transform.position);
  167. flashing = false;
  168. flashObject.GetComponent<Renderer>().material.color = originalColor;
  169. if(respawn)
  170. {
  171. Rigidbody rigid = GetComponent<Rigidbody>();
  172. if(rigid)
  173. rigid.velocity *= ;
  174. transform.position = respawnPos;
  175. dead = false;
  176. currentHealth = defHealth;
  177. }
  178. else
  179. Destroy (gameObject);
  180.  
  181. )
  182. foreach(GameObject obj in spawnOnDeath)
  183. Instantiate(obj, transform.position, Quaternion.Euler(Vector3.zero));
  184. }
  185.  
  186. void OnCollisionEnter(Collision col)
  187. {
  188. //播放撞击声音
  189. if(!aSource.isPlaying && impactSound)
  190. {
  191. aSource.clip = impactSound;
  192. aSource.volume = col.relativeVelocity.magnitude/;
  193. aSource.Play();
  194. }
  195.  
  196. //不会受到撞击伤害,返回
  197. if (!takeImpactDmg)
  198. return;
  199. //找到标签,返回
  200. foreach(string tag in impactFilterTag)
  201. if(col.transform.tag == tag)
  202. return;
  203. //只能受到刚体撞击且没有刚体,返回
  204. if(onlyRigidbodyImpact && !col.rigidbody)
  205. return;
  206.  
  207. //计算受到的伤害
  208. if(col.rigidbody)
  209. hitForce = ( * col.rigidbody.mass);
  210. else
  211. hitForce = (;
  212. currentHealth -= hitForce;
  213. //print (transform.name + " took: " + hitForce + " dmg in collision with " + col.transform.name);
  214. }
  215. }

Health

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. /// <summary>
  6. /// 移动到指定的点
  7. /// </summary>
  8. [RequireComponent(typeof(Rigidbody))]
  9. public class MoveToPoints:MonoBehaviour {
  10. /// <summary>
  11. /// 移动速度
  12. /// </summary>
  13. public float speed;
  14. /// <summary>
  15. /// 延迟
  16. /// </summary>
  17. public float delay;
  18. /// <summary>
  19. /// 移动类型
  20. /// </summary>
  21. public type movementType;
  22.  
  23. /// <summary>
  24. /// 移动类型
  25. /// </summary>
  26. public enum type {
  27. /// <summary>
  28. /// 在最后一个路标停止
  29. /// </summary>
  30. PlayOnce,
  31. /// <summary>
  32. /// 转圈
  33. /// </summary>
  34. Loop,
  35. /// <summary>
  36. /// 来回
  37. /// </summary>
  38. PingPong
  39. }
  40. /// <summary>
  41. /// 当前路标索引
  42. /// </summary>
  43. private int currentWp;
  44. /// <summary>
  45. /// 到达时间
  46. /// </summary>
  47. private float arrivalTime;
  48. /// <summary>
  49. /// 是否向前,是否到达
  50. /// </summary>
  51. private bool forward = true, arrived = false;
  52. /// <summary>
  53. /// 路标列表
  54. /// </summary>
  55. private List<Transform> waypoints = new List<Transform>();
  56. /// <summary>
  57. /// 角色移动
  58. /// </summary>
  59. private CharacterMotor characterMotor;
  60. /// <summary>
  61. /// 敌人AI
  62. /// </summary>
  63. private EnemyAI enemyAI;
  64. /// <summary>
  65. /// 刚体
  66. /// </summary>
  67. private Rigidbody rigid;
  68.  
  69. void Awake() {
  70. //标签不是Enemy
  71. if(transform.tag != "Enemy") {
  72. //没有刚体,添加刚体
  73. if(!GetComponent<Rigidbody>())
  74. gameObject.AddComponent<Rigidbody>();
  75. //动力学
  76. GetComponent<Rigidbody>().isKinematic = true;
  77. //不使用重力
  78. GetComponent<Rigidbody>().useGravity = false;
  79. //修改插值类型
  80. GetComponent<Rigidbody>().interpolation = RigidbodyInterpolation.Interpolate;
  81. } else {
  82. //角色移动
  83. characterMotor = GetComponent<CharacterMotor>();
  84. //获取敌人AI
  85. enemyAI = GetComponent<EnemyAI>();
  86. }
  87. //获取刚体
  88. rigid = GetComponent<Rigidbody>();
  89. //遍历子物体
  90. foreach(Transform child in transform)
  91. //添加路标
  92. if(child.tag == "Waypoint")
  93. waypoints.Add(child);
  94. //分离路标
  95. foreach(Transform waypoint in waypoints)
  96. waypoint.parent = null;
  97.  
  98. )
  99. Debug.LogError("No waypoints found for 'MoveToPoints' script. To add waypoints: add child gameObjects with the tag 'Waypoint'",transform);
  100. }
  101.  
  102. void Update() {
  103. //路标数量大于0
  104. ) {
  105. //没有到达
  106. if(!arrived) {
  107. //与下一个路标的距离小于0.3
  108. if(Vector3.Distance(transform.position,waypoints[currentWp].position) < 0.3f) {
  109. //设置到达时间
  110. arrivalTime = Time.time;
  111. //修改到达标志位
  112. arrived = true;
  113. }
  114. //到达
  115. } else {
  116. //当前时间大于到达时间加延迟
  117. if(Time.time > arrivalTime + delay) {
  118. //获取下一个路标
  119. GetNextWP();
  120. //修改到达标志位
  121. arrived = false;
  122. }
  123. }
  124. }
  125. //标签是Enemy,路标数量大于0
  126. ) {
  127. //没有到达位置
  128. if(!arrived) {
  129. //玩家移动到指定路标
  130. characterMotor.MoveTo(waypoints[currentWp].position,enemyAI.acceleration,0.1f,enemyAI.ignoreY);
  131. //播放动画
  132. if(enemyAI.animatorController)
  133. enemyAI.animatorController.SetBool("Moving",true);
  134. //到达位置
  135. } else
  136. //播放动画
  137. if(enemyAI.animatorController)
  138. enemyAI.animatorController.SetBool("Moving",false);
  139. }
  140. }
  141.  
  142. void FixedUpdate() {
  143. //标签为Enemy
  144. if(transform.tag != "Enemy") {
  145. //没有到达且路标数量大于0
  146. ) {
  147. //计算和路标的距离
  148. Vector3 direction = waypoints[currentWp].position - transform.position;
  149. //刚体移动
  150. rigid.MovePosition(transform.position + (direction.normalized * speed * Time.fixedDeltaTime));
  151. }
  152. }
  153. }
  154.  
  155. /// <summary>
  156. /// 获取下一个路标
  157. /// </summary>
  158. private void GetNextWP() {
  159. //一次
  160. if(movementType == type.PlayOnce) {
  161. currentWp++;
  162. if(currentWp == waypoints.Count)
  163. enabled = false;
  164. }
  165. //循环
  166. if(movementType == type.Loop)
  167. currentWp = (currentWp == waypoints.Count - ) ? : currentWp += ;
  168. //来回
  169. if(movementType == type.PingPong) {
  170. )
  171. forward = false;
  172. )
  173. forward = true;
  174. currentWp = (forward) ? currentWp += : currentWp -= ;
  175. }
  176. }
  177.  
  178. void OnDrawGizmos() {
  179. Gizmos.color = Color.cyan;
  180. foreach(Transform child in transform) {
  181. if(child.tag == "Waypoint")
  182. Gizmos.DrawSphere(child.position,.7f);
  183. }
  184. }
  185. }

MoveToPoints

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// 玩家移动
  6. /// </summary>
  7. [RequireComponent(typeof(CharacterMotor))]
  8. [RequireComponent(typeof(DealDamage))]
  9. [RequireComponent(typeof(AudioSource))]
  10. [RequireComponent(typeof(Rigidbody))]
  11. public class PlayerMove:MonoBehaviour {
  12. /// <summary>
  13. /// 是否是卷轴模式
  14. /// </summary>
  15. public bool sidescroller;
  16. /// <summary>
  17. /// 主相机,FloorChecks游戏物体Transform
  18. /// </summary>
  19. public Transform mainCam, floorChecks;
  20. /// <summary>
  21. /// Animator
  22. /// </summary>
  23. public Animator animator;
  24. /// <summary>
  25. /// 跳跃声音
  26. /// </summary>
  27. public AudioClip jumpSound;
  28. /// <summary>
  29. /// 着陆声音
  30. /// </summary>
  31. public AudioClip landSound;
  32.  
  33. /// <summary>
  34. /// 加速度
  35. /// </summary>
  36. public float accel = 70f;
  37. /// <summary>
  38. /// 空中加速度
  39. /// </summary>
  40. public float airAccel = 18f;
  41. /// <summary>
  42. /// 减速度
  43. /// </summary>
  44. public float decel = 7.6f;
  45. /// <summary>
  46. /// 空中减速度
  47. /// </summary>
  48. public float airDecel = 1.1f;
  49. /// <summary>
  50. /// 旋转速度,空中旋转速度
  51. /// </summary>
  52. [Range(0f,5f)]
  53. public float rotateSpeed = 0.7f, airRotateSpeed = 0.4f;
  54. /// <summary>
  55. /// 最高移动速度
  56. /// </summary>
  57. ;
  58. /// <summary>
  59. /// 最大坡度,最大滑坡速度
  60. /// </summary>
  61. , slideAmount = ;
  62. /// <summary>
  63. /// 移动平台的摩擦力
  64. /// </summary>
  65. public float movingPlatformFriction = 7.7f;
  66.  
  67. /// <summary>
  68. /// 常规跳跃力
  69. /// </summary>
  70. ,,);
  71. /// <summary>
  72. /// 2连跳力
  73. /// </summary>
  74. ,,);
  75. /// <summary>
  76. /// 3连跳力
  77. /// </summary>
  78. ,,);
  79. /// <summary>
  80. /// 两次跳跃间的延迟
  81. /// </summary>
  82. public float jumpDelay = 0.1f;
  83. /// <summary>
  84. /// 着陆前仍然可以按下跳跃的时间
  85. /// </summary>
  86. public float jumpLeniancy = 0.17f;
  87. [HideInInspector]
  88. public int onEnemyBounce;
  89. /// <summary>
  90. /// 跳跃类型
  91. /// </summary>
  92. private int onJump;
  93. /// <summary>
  94. /// 是否着陆
  95. /// </summary>
  96. private bool grounded;
  97. /// <summary>
  98. /// 检查是否着陆的Transform列表(玩家身体的下面9个点)
  99. /// </summary>
  100. private Transform[] floorCheckers;
  101. /// <summary>
  102. ///
  103. /// </summary>
  104. private Quaternion screenMovementSpace;
  105. /// <summary>
  106. /// 按下跳跃的时间,着陆后的时间,当前加速度,当前减速度,当前旋转速度,斜率
  107. /// </summary>
  108. private float airPressTime, groundedCount, curAccel, curDecel, curRotateSpeed, slope;
  109. /// <summary>
  110. /// 方向,移动方向,屏幕向前移动,屏幕向右移动,移动物体的速度
  111. /// </summary>
  112. private Vector3 direction, moveDirection, screenMovementForward, screenMovementRight, movingObjSpeed;
  113.  
  114. /// <summary>
  115. /// 角色移动
  116. /// </summary>
  117. private CharacterMotor characterMotor;
  118. /// <summary>
  119. /// 敌人AI
  120. /// </summary>
  121. private EnemyAI enemyAI;
  122. /// <summary>
  123. /// 处理伤害
  124. /// </summary>
  125. private DealDamage dealDamage;
  126. /// <summary>
  127. /// Rigidbody
  128. /// </summary>
  129. private Rigidbody rigid;
  130. /// <summary>
  131. /// AudioSource
  132. /// </summary>
  133. private AudioSource aSource;
  134.  
  135. void Awake() {
  136. //没有检查列表
  137. if(!floorChecks) {
  138. //添加
  139. floorChecks = new GameObject().transform;
  140. floorChecks.name = "FloorChecks";
  141. floorChecks.parent = transform;
  142. floorChecks.position = transform.position;
  143. //添加单个子物体
  144. GameObject check = new GameObject();
  145. check.name = "Check1";
  146. check.transform.parent = floorChecks;
  147. check.transform.position = transform.position;
  148. Debug.LogWarning("No 'floorChecks' assigned to PlayerMove script, so a single floorcheck has been created",floorChecks);
  149. }
  150. //标签不是Player
  151. if(tag != "Player") {
  152. //标签改为Player
  153. tag = "Player";
  154. Debug.LogWarning("PlayerMove script assigned to object without the tag 'Player', tag has been assigned automatically",transform);
  155. }
  156.  
  157. //获取主摄像机
  158. mainCam = GameObject.FindGameObjectWithTag("MainCamera").transform;
  159. //获取处理伤害
  160. dealDamage = GetComponent<DealDamage>();
  161. //获取角色移动
  162. characterMotor = GetComponent<CharacterMotor>();
  163. //获取刚体
  164. rigid = GetComponent<Rigidbody>();
  165. //获取AudioSource
  166. aSource = GetComponent<AudioSource>();
  167.  
  168. //设置检查列表
  169. floorCheckers = new Transform[floorChecks.childCount];
  170. ;i < floorCheckers.Length;i++)
  171. floorCheckers[i] = floorChecks.GetChild(i);
  172. }
  173.  
  174. void Update() {
  175. //激活刚体
  176. rigid.WakeUp();
  177. //计算跳跃
  178. JumpCalculations();
  179.  
  180. //根据玩家是否着地设置当前加速度
  181. curAccel = (grounded) ? accel : airAccel;
  182. //根据玩家是否着地设置当前减速度
  183. curDecel = (grounded) ? decel : airDecel;
  184. //根据玩家是否着地设置当前旋转速度
  185. curRotateSpeed = (grounded) ? rotateSpeed : airRotateSpeed;
  186.  
  187. screenMovementSpace = Quaternion.Euler(,mainCam.eulerAngles.y,);
  188. screenMovementForward = screenMovementSpace * Vector3.forward;
  189. screenMovementRight = screenMovementSpace * Vector3.right;
  190.  
  191. float h = Input.GetAxisRaw("Horizontal");
  192. float v = Input.GetAxisRaw("Vertical");
  193.  
  194. //不是卷轴模式
  195. if(!sidescroller)
  196. direction = (screenMovementForward * v) + (screenMovementRight * h);
  197. //是卷轴模式
  198. else
  199. //方向等于水平轴的输入*Vector3.right
  200. direction = Vector3.right * h;
  201. //移动方向等于当前位置加方向
  202. moveDirection = transform.position + direction;
  203. }
  204.  
  205. void FixedUpdate() {
  206. //检查是否着地
  207. grounded = IsGrounded();
  208. //角色移动
  209. characterMotor.MoveTo(moveDirection,curAccel,0.7f,true);
  210. //旋转角色
  211. && direction.magnitude != )
  212. characterMotor.RotateToDirection(moveDirection,curRotateSpeed * ,true);
  213. //管理角色速度
  214. characterMotor.ManageSpeed(curDecel,maxSpeed + movingObjSpeed.magnitude,true);
  215. //播放动画
  216. if(animator) {
  217. animator.SetFloat("DistanceToTarget",characterMotor.DistanceToTarget);
  218. animator.SetBool("Grounded",grounded);
  219. animator.SetFloat("YVelocity",GetComponent<Rigidbody>().velocity.y);
  220. }
  221. }
  222.  
  223. void OnCollisionStay(Collision other) {
  224. if(other.collider.tag != "Untagged" || grounded == false)
  225. return;
  226. //在小坡度上停止下滑
  227. && slope < slopeLimit && rigid.velocity.magnitude < ) {
  228. rigid.velocity = Vector3.zero;
  229. }
  230. }
  231.  
  232. /// <summary>
  233. /// 检查是否着陆
  234. /// </summary>
  235. private bool IsGrounded() {
  236. //计算距离
  237. float dist = GetComponent<Collider>().bounds.extents.y;
  238.  
  239. //遍历所有检查点
  240. foreach(Transform check in floorCheckers) {
  241. RaycastHit hit;
  242. //向下发射射线
  243. if(Physics.Raycast(check.position,Vector3.down,out hit,dist + 0.05f)) {
  244. //如果不是触发器
  245. if(!hit.transform.GetComponent<Collider>().isTrigger) {
  246. //计算斜率
  247. slope = Vector3.Angle(hit.normal,Vector3.up);
  248. //斜率大于最大斜率,不是Pushable
  249. if(slope > slopeLimit && hit.transform.tag != "Pushable") {
  250. //计算滑动方向
  251. Vector3 slide = new Vector3(0f,-slideAmount,0f);
  252. //刚体施加滑动力
  253. rigid.AddForce(slide,ForceMode.Force);
  254. }
  255. //碰到敌人,y轴速度小于0
  256. ) {
  257. //获取敌人AI
  258. enemyAI = hit.transform.GetComponent<EnemyAI>();
  259. //弹开玩家
  260. enemyAI.BouncedOn();
  261. //
  262. onEnemyBounce++;
  263. //处理伤害
  264. dealDamage.Attack(hit.transform.gameObject,,0f,0f);
  265. } else
  266. //
  267. onEnemyBounce = ;
  268. //移动平台或Pushable
  269. if(hit.transform.tag == "MovingPlatform" || hit.transform.tag == "Pushable") {
  270. //移动物体的速度为刚体的速度
  271. movingObjSpeed = hit.transform.GetComponent<Rigidbody>().velocity;
  272. //移动物体的y轴速度为0
  273. movingObjSpeed.y = 0f;
  274. //根据移动物体的速度和摩檫力给玩家刚体添加力
  275. rigid.AddForce(movingObjSpeed * movingPlatformFriction * Time.fixedDeltaTime,ForceMode.VelocityChange);
  276. } else {
  277. //移动物体的速度归0
  278. movingObjSpeed = Vector3.zero;
  279. }
  280. return true;
  281. }
  282. }
  283. }
  284. //移动物体的速度归0
  285. movingObjSpeed = Vector3.zero;
  286. return false;
  287. }
  288.  
  289. /// <summary>
  290. /// 计算跳跃
  291. /// </summary>
  292. private void JumpCalculations() {
  293. //保存着陆后的时间
  294. groundedCount = (grounded) ? groundedCount += Time.deltaTime : 0f;
  295.  
  296. //着陆时间小于0.25并且不等于0,正在播放声音,y轴的速度小于1
  297. && !GetComponent<AudioSource>().isPlaying && landSound && GetComponent<Rigidbody>().velocity.y < ) {
  298. //根据y轴的速度修改音量
  299. aSource.volume = Mathf.Abs(GetComponent<Rigidbody>().velocity.y) / ;
  300. //修改声音
  301. aSource.clip = landSound;
  302. //播放声音
  303. aSource.Play();
  304. }
  305. //按下jump且没有着陆
  306. if(Input.GetButtonDown("Jump") && !grounded)
  307. //修改按下跳跃的时间为当前时间
  308. airPressTime = Time.time;
  309.  
  310. //着陆,斜率小于最大斜率
  311. if(grounded && slope < slopeLimit) {
  312. //按下Jump
  313. if(Input.GetButtonDown("Jump") || airPressTime + jumpLeniancy > Time.time) {
  314. //切换跳跃类型
  315. onJump = (groundedCount < jumpDelay) ? Mathf.Min(,onJump + ) : ;
  316.  
  317. )
  318. Jump(jumpForce);
  319. )
  320. Jump(secondJumpForce);
  321. ) {
  322. Jump(thirdJumpForce);
  323. onJump--;
  324. }
  325. }
  326. }
  327. }
  328.  
  329. /// <summary>
  330. /// 跳跃
  331. /// </summary>
  332. public void Jump(Vector3 jumpVelocity) {
  333. //播放跳跃声音
  334. if(jumpSound) {
  335. aSource.volume = ;
  336. aSource.clip = jumpSound;
  337. aSource.Play();
  338. }
  339. //改变刚体的y轴速度
  340. rigid.velocity = new Vector3(rigid.velocity.x,0f,rigid.velocity.z);
  341. //给刚体添加力
  342. rigid.AddRelativeForce(jumpVelocity,ForceMode.Impulse);
  343. //重置按下跳跃的时间
  344. airPressTime = 0f;
  345. }
  346. }

PlayerMove

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// 让玩家拾取,扔,推物体
  6. /// </summary>
  7. [RequireComponent(typeof(AudioSource))]
  8. [RequireComponent(typeof(Rigidbody))]
  9. [RequireComponent(typeof(PlayerMove))]
  10. public class Throwing : MonoBehaviour
  11. {
  12. /// <summary>
  13. /// 拾取声音
  14. /// </summary>
  15. public AudioClip pickUpSound;
  16. /// <summary>
  17. /// 扔声音
  18. /// </summary>
  19. public AudioClip throwSound;
  20. /// <summary>
  21. /// 用来抓物体的子游戏物体
  22. /// </summary>
  23. public GameObject grabBox;
  24. /// <summary>
  25. /// 举起物体的偏移
  26. /// </summary>
  27. public Vector3 holdOffset;
  28. /// <summary>
  29. /// 扔的力
  30. /// </summary>
  31. , , );
  32. /// <summary>
  33. /// 转向物体的速度
  34. /// </summary>
  35. ;
  36. /// <summary>
  37. /// 检查玩家头部的范围
  38. /// </summary>
  39. public float checkRadius = 0.5f;
  40. /// <summary>
  41. /// 拾取物体的重量
  42. /// </summary>
  43. [Range(0.1f, 1f)]
  44. public float weightChange = 0.3f;
  45. /// <summary>
  46. /// 未用
  47. /// </summary>
  48. [Range(10f, 1000f)]
  49. , holdingBreakTorque = ;
  50. /// <summary>
  51. /// Animator
  52. /// </summary>
  53. public Animator animator;
  54. /// <summary>
  55. /// 手臂动画层
  56. /// </summary>
  57. public int armsAnimationLayer;
  58.  
  59. /// <summary>
  60. /// 举起或抓住的物体
  61. /// </summary>
  62. [HideInInspector]
  63. public GameObject heldObj;
  64. /// <summary>
  65. /// 举起物体的位置
  66. /// </summary>
  67. private Vector3 holdPos;
  68. /// <summary>
  69. /// 连接物体和角色的关节
  70. /// </summary>
  71. private FixedJoint joint;
  72. /// <summary>
  73. /// 举起物体的时间,扔物体的时间,默认旋转速度
  74. /// </summary>
  75. private float timeOfPickup, timeOfThrow, defRotateSpeed;
  76. /// <summary>
  77. /// gizmo颜色
  78. /// </summary>
  79. private Color gizmoColor;
  80. /// <summary>
  81. /// AudioSource
  82. /// </summary>
  83. private AudioSource aSource;
  84. /// <summary>
  85. /// 玩家移动
  86. /// </summary>
  87. private PlayerMove playerMove;
  88. /// <summary>
  89. /// 父物体下的子物体的触发器
  90. /// </summary>
  91. private TriggerParent triggerParent;
  92. /// <summary>
  93. /// 默认刚体插值类型
  94. /// </summary>
  95. private RigidbodyInterpolation objectDefInterpolation;
  96.  
  97. void Awake()
  98. {
  99. //获取AudioSource
  100. aSource = GetComponent<AudioSource>();
  101. //没有抓物体的子物体
  102. if(!grabBox)
  103. {
  104. //新建
  105. grabBox = new GameObject();
  106. //添加碰撞器
  107. grabBox.AddComponent<BoxCollider>();
  108. //设置为触发器
  109. grabBox.GetComponent<Collider>().isTrigger = true;
  110. //设置玩家为父物体
  111. grabBox.transform.parent = transform;
  112. //修改局部坐标
  113. grabBox.transform.localPosition = new Vector3(0f, 0f, 0.5f);
  114. //修改层(Ignore Raycast)
  115. grabBox.layer = ;
  116. Debug.LogWarning("No grabBox object assigned to 'Throwing' script, one has been created and assigned for you", grabBox);
  117. }
  118. //获取玩家移动脚本
  119. playerMove = GetComponent<PlayerMove>();
  120. //设置默认旋转速度
  121. defRotateSpeed = playerMove.rotateSpeed;
  122. //Animator不为空
  123. if(animator)
  124. //设置手臂动画层的权重
  125. animator.SetLayerWeight(armsAnimationLayer, );
  126. }
  127.  
  128. void Update()
  129. {
  130. //按下Grab键,有举起或抓住的物体,当前时间比举起物体的时间大0.1f
  131. if (Input.GetButtonDown ("Grab") && heldObj && Time.time > timeOfPickup + 0.1f)
  132. {
  133. //举起物体的标签为"Pickup"
  134. if(heldObj.tag == "Pickup")
  135. //扔掉举起的物体
  136. ThrowPickup();
  137. }
  138. //有Animator
  139. if(animator)
  140. //有举起的物体且物体标签为"Pickup"
  141. if(heldObj && heldObj.tag == "Pickup")
  142. animator.SetBool ("HoldingPickup", true);
  143. else
  144. animator.SetBool ("HoldingPickup", false);
  145. //有抓住的物体且物体标签为"Pushable"
  146. if(heldObj && heldObj.tag == "Pushable")
  147. animator.SetBool ("HoldingPushable", true);
  148. else
  149. animator.SetBool ("HoldingPushable", false);
  150.  
  151. //有抓住的物体且物体标签为"Pushable"
  152. if (heldObj && heldObj.tag == "Pushable")
  153. {
  154. //按下Grab
  155. if(Input.GetButtonUp ("Grab"))
  156. {
  157. //丢弃物体
  158. DropPushable();
  159. }
  160. //没有关节
  161. if(!joint)
  162. {
  163. //丢弃物体
  164. DropPushable();
  165. print ("'Pushable' object dropped because the 'holdingBreakForce' or 'holdingBreakTorque' was exceeded");
  166. }
  167. }
  168. }
  169.  
  170. void OnTriggerStay(Collider other)
  171. {
  172. //按下Grab
  173. if(Input.GetButton("Grab"))
  174. {
  175. //标签为"Pickup",没有举起的物体,当前时间大于扔物体的时间加0.2
  176. if(other.tag == "Pickup" && heldObj == null && timeOfThrow + 0.2f < Time.time)
  177. //举起物体
  178. LiftPickup(other);
  179. //标签为"Pushable",没有抓住的物体,当前时间大于扔物体的时间加0.2
  180. if(other.tag == "Pushable" && heldObj == null && timeOfThrow + 0.2f < Time.time)
  181. //抓物体
  182. GrabPushable(other);
  183. }
  184. }
  185.  
  186. /// <summary>
  187. /// 抓住物体
  188. /// </summary>
  189. private void GrabPushable(Collider other)
  190. {
  191. //抓住的物体为碰撞的物体
  192. heldObj = other.gameObject;
  193. //获取物体的插值类型
  194. objectDefInterpolation = heldObj.GetComponent<Rigidbody>().interpolation;
  195. //修改物体的插值为内插值
  196. heldObj.GetComponent<Rigidbody>().interpolation = RigidbodyInterpolation.Interpolate;
  197. //添加关节,连接玩家和物体
  198. AddJoint ();
  199. //设置破坏关节的力为无限
  200. joint.breakForce = Mathf.Infinity;
  201. //设置破坏关节的扭矩力为无限
  202. joint.breakTorque = Mathf.Infinity;
  203. //设置玩家移动的旋转速度为0
  204. playerMove.rotateSpeed = ;
  205. }
  206.  
  207. /// <summary>
  208. /// 举起物体
  209. /// </summary>
  210. private void LiftPickup(Collider other)
  211. {
  212. //获取物体的网格
  213. Mesh otherMesh = other.GetComponent<MeshFilter>().mesh;
  214. //计算举起的位置
  215. holdPos = transform.position + transform.forward * holdOffset.z + transform.right * holdOffset.x + transform.up * holdOffset.y;
  216. //举起的位置的y值加碰撞器的范围的y值加碰撞物体网格的范围的y值
  217. holdPos.y += (GetComponent<Collider>().bounds.extents.y) + (otherMesh.bounds.extents.y);
  218.  
  219. //检测举起位置的圆形范围
  220. if(!Physics.CheckSphere(holdPos,checkRadius)) {
  221. //修改gizmo颜色
  222. gizmoColor = Color.green;
  223. //缓存举起的物体
  224. heldObj = other.gameObject;
  225. //修改默认插值类型
  226. objectDefInterpolation = heldObj.GetComponent<Rigidbody>().interpolation;
  227. //修改举起物体的插值类型
  228. heldObj.GetComponent<Rigidbody>().interpolation = RigidbodyInterpolation.Interpolate;
  229. //修改举起物体的位置
  230. heldObj.transform.position = holdPos;
  231. //修改举起物体的旋转
  232. heldObj.transform.rotation = transform.rotation;
  233. //添加关节,连接物体和玩家
  234. AddJoint();
  235. //修改举起物体的质量
  236. heldObj.GetComponent<Rigidbody>().mass *= weightChange;
  237. //修改举起物体的时间为当前时间
  238. timeOfPickup = Time.time;
  239. } else {
  240. //修改gizmo颜色
  241. gizmoColor = Color.red;
  242. print("Can't lift object here. If nothing is above the player, perhaps you need to add a layerMask parameter to line 136 of the code in this script," +
  243. "the CheckSphere function, in order to make sure it isn't detecting something above the players head that is invisible");
  244. }
  245. }
  246.  
  247. /// <summary>
  248. /// 放下物体
  249. /// </summary>
  250. private void DropPushable()
  251. {
  252. //修改抓住物体的插值类型
  253. heldObj.GetComponent<Rigidbody>().interpolation = objectDefInterpolation;
  254. //销毁关节
  255. Destroy (joint);
  256. //修改玩家移动的旋转速度为默认旋转速度
  257. playerMove.rotateSpeed = defRotateSpeed;
  258. heldObj = null;
  259. timeOfThrow = Time.time;
  260. }
  261.  
  262. /// <summary>
  263. /// 扔掉物体
  264. /// </summary>
  265. public void ThrowPickup()
  266. {
  267. //播放扔物体声音
  268. if(throwSound)
  269. {
  270. aSource.volume = ;
  271. aSource.clip = throwSound;
  272. aSource.Play ();
  273. }
  274. //删除关节
  275. Destroy (joint);
  276. //获取举起物体的刚体
  277. Rigidbody r = heldObj.GetComponent<Rigidbody>();
  278. //恢复物体的插值类型
  279. r.interpolation = objectDefInterpolation;
  280. //恢复物体的质量
  281. r.mass /= weightChange;
  282. //给刚体添加力
  283. r.AddRelativeForce (throwForce, ForceMode.VelocityChange);
  284.  
  285. heldObj = null;
  286. timeOfThrow = Time.time;
  287. }
  288.  
  289. /// <summary>
  290. /// 添加关节,连接玩家和物体
  291. /// </summary>
  292. private void AddJoint()
  293. {
  294. //如果有物体
  295. if (heldObj)
  296. {
  297. //播放拾取声音
  298. if(pickUpSound)
  299. {
  300. aSource.volume = ;
  301. aSource.clip = pickUpSound;
  302. aSource.Play ();
  303. }
  304. //在物体上添加关节
  305. joint = heldObj.AddComponent<FixedJoint>();
  306. //设置关节的连接物体为玩家的刚体
  307. joint.connectedBody = GetComponent<Rigidbody>();
  308. }
  309. }
  310.  
  311. void OnDrawGizmosSelected()
  312. {
  313. Gizmos.color = gizmoColor;
  314. Gizmos.DrawSphere (holdPos, checkRadius);
  315. }
  316. }

Throwing

  1. using UnityEngine;
  2. using System.Collections;
  3.  
  4. /// <summary>
  5. /// 父物体下的子物体的触发器
  6. /// </summary>
  7. public class TriggerParent:MonoBehaviour {
  8.  
  9. /// <summary>
  10. /// 要检查的标签列表
  11. /// </summary>
  12. public string[] tagsToCheck;
  13.  
  14. /// <summary>
  15. /// 是否发生了碰撞,是否在碰撞中
  16. /// </summary>
  17. [HideInInspector]
  18. public bool collided, colliding;
  19. /// <summary>
  20. /// 撞击的物体
  21. /// </summary>
  22. [HideInInspector]
  23. public GameObject hitObject;
  24.  
  25. void Awake() {
  26. //没有Collider或有Collider但不是触发器
  27. if(!GetComponent<Collider>() || (GetComponent<Collider>() && !GetComponent<Collider>().isTrigger))
  28. Debug.LogError("'TriggerParent' script attached to object which does not have a trigger collider",transform);
  29. }
  30.  
  31. void OnTriggerEnter(Collider other) {
  32. //标签列表长度大于0且没有碰撞过
  33. && !collided) {
  34. //遍历标签
  35. foreach(string tag in tagsToCheck) {
  36. //找到标签
  37. if(other.tag == tag) {
  38. //已发生碰撞
  39. collided = true;
  40. //存储碰撞物体
  41. hitObject = other.gameObject;
  42. break;
  43. }
  44.  
  45. }
  46. } else
  47. //已发生碰撞
  48. collided = true;
  49. //存储碰撞物体
  50. hitObject = other.gameObject;
  51. }
  52.  
  53. void OnTriggerStay(Collider other) {
  54. //标签列表长度大于0
  55. ) {
  56. //遍历标签
  57. foreach(string tag in tagsToCheck) {
  58. //找到标签
  59. if(other.tag == tag) {
  60. //正在碰撞
  61. colliding = true;
  62. //存储碰撞物体
  63. hitObject = other.gameObject;
  64. break;
  65. }
  66. }
  67. } else {
  68. //存储碰撞物体
  69. hitObject = other.gameObject;
  70. //正在碰撞
  71. colliding = true;
  72. }
  73. }
  74.  
  75. void OnTriggerExit(Collider other) {
  76. //标签列表长度大于0
  77. ) {
  78. //遍历标签
  79. foreach(string tag in tagsToCheck) {
  80. //找到标签
  81. if(other.tag == tag) {
  82. colliding = false;
  83. hitObject = null;
  84. break;
  85. }
  86. }
  87. } else
  88. return;
  89. }
  90.  
  91. void LateUpdate() {
  92. //重置collided,hitObject
  93. if(collided) {
  94. collided = false;
  95. hitObject = null;
  96. }
  97. }
  98. }

TriggerParent

  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. /// <summary>
  6. /// 水
  7. /// </summary>
  8. [RequireComponent(typeof(BoxCollider))]
  9. public class Water:MonoBehaviour {
  10. /// <summary>
  11. /// 玩家进水的声音
  12. /// </summary>
  13. public AudioClip splashSound;
  14. /// <summary>
  15. /// 水的推力
  16. /// </summary>
  17. ,);
  18. /// <summary>
  19. /// 玩家是否会受到水的阻力影响
  20. /// </summary>
  21. public bool effectPlayerDrag;
  22. /// <summary>
  23. /// 刚体受到的水的阻力(不包含玩家)
  24. /// </summary>
  25. public float resistance = 0.4f;
  26. /// <summary>
  27. /// 刚体受到的角阻力(不包含玩家)
  28. /// </summary>
  29. public float angularResistance = 0.2f;
  30.  
  31. /// <summary>
  32. /// 刚体受到的阻力字典
  33. /// </summary>
  34. private Dictionary<GameObject,float> dragStore = new Dictionary<GameObject,float>();
  35. /// <summary>
  36. /// 刚体受到的角阻力字典
  37. /// </summary>
  38. private Dictionary<GameObject,float> angularStore = new Dictionary<GameObject,float>();
  39.  
  40. void Awake() {
  41. //自动修改"Water"标签
  42. if(tag != "Water") {
  43. tag = "Water";
  44. Debug.LogWarning("'Water' script attached to an object not tagged 'Water', it been assigned the tag 'Water'",transform);
  45. }
  46. //设置Trigger
  47. GetComponent<Collider>().isTrigger = true;
  48. }
  49.  
  50. void OnTriggerEnter(Collider other) {
  51. //获取物体的刚体
  52. Rigidbody r = other.GetComponent<Rigidbody>();
  53. //刚体不为空
  54. if(r) {
  55. //播放入水声音
  56. if(splashSound) {
  57. ;
  58. AudioSource.PlayClipAtPoint(splashSound,other.transform.position,volume);
  59. }
  60.  
  61. //是玩家且不受水的阻力影响
  62. if(r.tag == "Player" && !effectPlayerDrag)
  63. return;
  64.  
  65. //存储受到的阻力
  66. dragStore.Add(r.gameObject,r.drag);
  67. //存储受到的角阻力
  68. angularStore.Add(r.gameObject,r.angularDrag);
  69.  
  70. //修改刚体受到的阻力
  71. r.drag = resistance;
  72. //修改刚体受到的角阻力
  73. r.angularDrag = angularResistance;
  74. } else if(splashSound)
  75. //播放入水声音
  76. AudioSource.PlayClipAtPoint(splashSound,other.transform.position);
  77. }
  78.  
  79. void OnTriggerStay(Collider other) {
  80. //计算表面高度
  81. float surface = transform.position.y + GetComponent<Collider>().bounds.extents.y;
  82. Rigidbody rigid = other.GetComponent<Rigidbody>();
  83. if(rigid) {
  84. //计算物体相对于表面高度的深度
  85. float depth = surface - other.transform.position.y;
  86. //深度大于0.4
  87. if(depth > 0.4f)
  88. //用一个较小的力往上推刚体
  89. rigid.AddForce(force,ForceMode.Force);
  90. //深度小于等于0.4
  91. else
  92. //用一个较大的力往上推刚体
  93. rigid.AddForce(force * (depth * ),ForceMode.Force);
  94. }
  95. }
  96.  
  97. void OnTriggerExit(Collider other) {
  98. //获取物体的刚体
  99. Rigidbody r = other.GetComponent<Rigidbody>();
  100. //有刚体
  101. if(r) {
  102. //是玩家且不受阻力水的阻力影响
  103. if(r.tag == "Player" && !effectPlayerDrag)
  104. return;
  105.  
  106. //阻力和角阻力字典包含刚体的游戏物体
  107. if(dragStore.ContainsKey(r.gameObject) && angularStore.ContainsKey(r.gameObject)) {
  108. //恢复阻力
  109. r.drag = dragStore[r.gameObject];
  110. //恢复角阻力
  111. r.angularDrag = angularStore[r.gameObject];
  112. //移除阻力
  113. dragStore.Remove(r.gameObject);
  114. //移除角阻力
  115. angularStore.Remove(r.gameObject);
  116. } else {
  117. //重置阻力
  118. r.drag = 0f;
  119. //重置角阻力
  120. r.angularDrag = 0.05f;
  121. print("Object left water: couldn't get drag values, restored to defaults");
  122. }
  123. }
  124. }
  125. }

Water

视频:https://pan.baidu.com/s/1mhF7hmo

项目:https://pan.baidu.com/s/1pL6nMTP

Complete Physics Platformer Kit 学习的更多相关文章

  1. iOS7 Sprite Kit 学习

    iOS7 Sprite Kit 学习 iOS 7有一个新功能 Sprite Kit 这个有点类似cocos2d 感觉用法都差不多.下面简单来介绍下Sprite Kit About Sprite Kit ...

  2. S老师 Top-Down RPG Starter Kit 学习

    character creation using UnityEngine; using System.Collections; public class CharacterCreation : Mon ...

  3. Sprite Kit编程指南(1)-深入Sprite Kit

    深入Sprite Kit 学习Sprite Kit最好的方法是在实践中观察它.此示例创建一对场景和各自的动画内容.通过这个例子,你将学习使用Sprite Kit内容的一些基础技术,包括: ·      ...

  4. [Unity3D]Unity资料大全免费分享

     都是网上找的连七八糟的资料了,整理好分享的,有学习资料,视频,源码,插件……等等 东西比较多,不是所有的都是你需要的,可以按  ctrl+F 来搜索你要的东西,如果有广告,不用理会,关掉就可以了,如 ...

  5. 【转】iOS 开发怎么入门?

    原文网址:http://www.zhihu.com/question/20264108 iOS 开发怎么入门? 请问有设计模式.内存管理方面的资料吗?最好有除了官方文档之外的其它内容,10 条评论 分 ...

  6. DirectX SDK版本与Visual Studio版本

    对于刚刚接触 DirectShow 的人来说,安装配置是一个令人头疼的问题,经常出现的情况是最基本的 baseclass 就无法编译.一开始我也为此费了很大的功夫,比如说修改代码.修改编译选项使其编译 ...

  7. How to Write Doc Comments for the Javadoc Tool

    http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html This document describe ...

  8. DirectX

    DirectX 9.0 Complete Software Development Kit (SDK) :(2002-12-19) 点击下载 DirectX 9.0 SDK Update - (Sum ...

  9. 转 springboot 教程

    转 Spring Boot 揭秘与实战 系列 拓展阅读: https://zhuanlan.zhihu.com/dreawer?topic=Java 发表于 2016-12-21 | Spring框架 ...

随机推荐

  1. 开发框架DevExtreme全新发布v18.2.6|附下载

    DevExtreme Complete Subscription是性能最优的 HTML5,CSS 和 JavaScript 移动.Web开发框架,可以直接在Visual Studio集成开发环境,构建 ...

  2. 实现html转png

    公司要求将一些重要数据全部以图片的形式放在官网上,防止网络爬虫. 之前都是UI作图,人工上传,为了解放生产力,于是我们程序处理. 步骤: 1.html得到与原图一致的图片(交给前端处理) 2.html ...

  3. kettle在linux下执行任务

    1.下载 最新版下载 7.1 https://community.hitachivantara.com/docs/DOC-1009855 准备 上传任务文件 .kjb,.ktr 上传mysql 驱动 ...

  4. L230 RF可靠性测试-RF指标

    最近调试Zigbee 和2.4G产品时需要做一些认证,查找到常用的RF指标. ----------http://www.52rd.com/S_TXT/2016_5/TXT83303.htm------ ...

  5. <context:annotation-config/>和<mvc:annotation-driven/>及解决No mapping found for HTTP request with URI [/role/getRole] in DispatcherServlet with name 'springmvc-config'

    1:什么时候使用<context:annotation-config> 当你使用@Autowired,@Required,@Resource,@PostConstruct,@PreDest ...

  6. array_multisort

    项目中用到这个函数了 ,起初对这个函数一直是懵逼状态,文档都看的朦朦胧胧的 网上无意间看到这篇文章 ,写的超级详细,收藏了 . 当然要先放原地址:https://www.cnblogs.com/WuN ...

  7. 解析XML技术

    转载:http://developer.51cto.com/art/200903/117512.htm XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交 ...

  8. JavaScript条件语句4--分支语句--if

    JavaScript条件语句--分支语句 学习目标 1.掌握条件语句if 2.掌握prompt()的应用 3.掌握alert的应用 If语句 语法一: If(condition){ statement ...

  9. Android内核栈溢出与ROP(CVE-2013-2597)

    一.准备 由于内核栈不可执行(NX),栈溢出利用需用到ROP.简单回顾一下ARM ROP. 漏洞演示代码如下,网上随便找了个. char *str="/system/bin/sh" ...

  10. tmux不自动加载配置文件.tmux.conf

    /********************************************************************** * tmux不自动加载配置文件.tmux.conf * ...