今天继续来总结做的Unity基础练习
我觉得以后直接把我做练习过程中感觉困难的点或者是一些可以优化的点,以及教程的一些思路写出来。就不转述整体框架了。
今天的教程来自于:
Unity基础练习,运动1
这次练习1完成的是一个可运动的小球,在不使用物理引擎的情况下实现控制小球运动范围,速度控制以及加速度还有碰撞回弹效果。
完整脚本代码如下,附带了详细的注释:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingSphere : MonoBehaviour
{
//下方SerializeField对Unity字段序列化,这意味着它已保存在Unity编译器中公开
//该字段仍然不受该类之外的代码影响
[SerializeField,Range(0f,100f)]
float maxSpeed = 10f;//调整速度
[SerializeField,Range(0f,100f)]
float maxAcceleration = 10f;//调整加速度
[SerializeField]
Rect allowedArea = new Rect(-5f,-5f,10f,10f);//新建了一个矩形结构体
[SerializeField,Range(0f,1f)]
float bounciness = 0.5f;//碰撞反弹量
Vector3 velocity;//跟踪速度
void Update(){
Vector2 playerInput;//用一个Vector2来存储玩家的二维移动指令
playerInput.x = Input.GetAxis("Horizontal");//让小球水平移动
playerInput.y = Input.GetAxis("Vertical");//让小球垂直移动
//上面这种方法控制移动是一种默认绑定
//你可以从Edit——Project Setting——input中查看相关的设置
playerInput = Vector2.ClampMagnitude(playerInput,1f);
// playerInput.Normalize(); //该函数确保矢量不大于1,或者是使用上方ClampMagnitude方法
//确保矢量不大于1可以让斜着走和其它方向的移动保持相同速度
Vector3 desiredVelocity = new Vector3(playerInput.x,0f,playerInput.y)*maxSpeed;
float maxSpeedChange = maxAcceleration * Time.deltaTime;//更新速度的幅度
// if(velocity.x < desiredVelocity.x)
// {
// velocity.x = Mathf.Min(velocity.x+maxSpeedChange,desiredVelocity.x);//选取最小值消除过冲
// }
// else if(velocity.x>desiredVelocity.x){
// velocity.x = Mathf.Max(velocity.x-maxSpeedChange,desiredVelocity.x);//选取最大值消除过冲效应
// }
//上方判定代码的简化:
//该函数返回值为 1+3<2? 1+3:2
velocity.x = Mathf.MoveTowards(velocity.x,desiredVelocity.x,maxSpeedChange);
velocity.z = Mathf.MoveTowards(velocity.z,desiredVelocity.z,maxSpeedChange);
Vector3 displacement = velocity*Time.deltaTime;//使用Time消除帧速率对速度的影响
Vector3 newPosition = transform.localPosition + displacement;//通过约束新位置来约束球体
if(!allowedArea.Contains(new Vector2(newPosition.x,newPosition.z)))//检查新位置是不是被包含允许区域之内,同时保证维度相同
{
// Mathf.Clamp(float value,float min,float max)
// 在 Mathf.Clamp 中传入三个参数:value,min,max
// 限制 value的值在min,max之间,如果value大于max,则返回max,如果value小于min,则返回min,否者返回value;
// newPosition.x =
// Mathf.Clamp(newPosition.x,allowedArea.xMin,allowedArea.xMax);//让碰撞不要那么生硬
// newPosition.z =
// Mathf.Clamp(newPosition.z,allowedArea.yMin,allowedArea.yMax);
//以下代码是在不使用刚体和碰撞组件的情况下模拟碰撞,让小球可以快速离开墙面,而不受本来速度的影响
if(newPosition.x<allowedArea.xMin){
newPosition.x = allowedArea.xMin;
velocity.x = -velocity.x+bounciness;//模拟弹回
}
else if(newPosition.x>allowedArea.xMax){
newPosition.x = allowedArea.xMax;
velocity.x = -velocity.x+bounciness;//模拟弹回
}
if(newPosition.z<allowedArea.yMin){
newPosition.z = allowedArea.yMin;
velocity.z = -velocity.z+bounciness;//模拟弹回
}
else if(newPosition.z>allowedArea.yMax){
newPosition.z = allowedArea.yMax;
velocity.z = -velocity.z+bounciness;//模拟弹回
}
}
transform.localPosition = newPosition;
}
}
一些注意事项:
1.Trail Renderer(轨迹组件)需求的材质在Unity2020中需要设置成Particles/Standard Unit
2.Input.GetAxis()函数控制移动,该方法的移动使用的键位是默认值。
你可以从Edit——Project Setting——input中查看相关的设置
3.【SerializeField,Range(x,y)】对Unity字段序列化,等于向编译器公开该序列。但是该字段仍然不会受除了定义类以外的别的类影响
4.ClampManitude(vector,x)可以限制向量的最大长度为x。
当x=1f时,该方法可以控制斜着走的速度(一般来说是根号二倍)与其它方向的速度相同。
5.使用Time清除帧速率对速度的影响。(主要是针对Update帧率不固定的更新方法)
6.使用Mathf.Clamp()使小球和边缘的碰撞更平滑