您现在的位置是:首页 >其他 >【学习笔记】unity脚本学习(四)【inputManager、键盘输入、鼠标输入、Raycast】网站首页其他
【学习笔记】unity脚本学习(四)【inputManager、键盘输入、鼠标输入、Raycast】
目录
输入
inputManager
Horizontal虚拟轴的各个属性含义(摘选自ChatGpt,部分回答不准确)
- Name:虚拟轴的名称,用于在代码中访问该虚拟轴。这个名称应该是唯一的,用于区分其他虚拟轴。
- Descriptive Name:描述虚拟轴的名称,用于在Inspector中显示。这个名称通常是用户友好的,例如"水平轴"、"左右方向"等。
- Negative Button:定义一个负向按钮,按下这个按钮将使轴值变为负数。这个按钮可以是Unity中默认定义的按键(例如左箭头键、A键等),也可以是用户自定义的按键。如果不需要负向按钮,可以将其留空。
- Positive Button:定义一个正向按钮,按下这个按钮将使轴值变为正数。同样,这个按钮可以是默认定义的按键或者自定义的按键。如果不需要正向按钮,可以将其留空。
- Alt Negative Button:定义一个替代的负向按钮。如果定义了这个按钮,当Negative Button按钮没有被按下时,按下这个替代按钮也可以使轴值变为负数。如果不需要替代按钮,可以将其留空。
- Alt Positive Button:定义一个替代的正向按钮。同样,当Positive Button按钮没有被按下时,按下这个替代按钮也可以使轴值变为正数。如果不需要替代按钮,可以将其留空。
- Gravity:轴值的“重力”,表示轴值在没有按下按钮时逐渐趋向于0的速度。例如,如果Gravity属性设置为1,则当没有按下任何控制键时,轴值每秒钟会减少1。这可以使物体在没有输入时自然地停下来。如果Gravity属性设置为0,则轴值将永远不会自动返回0。
- Dead:死区,当轴值的绝对值小于这个值时,轴值将被认为是0。死区通常用于解决输入设备的精度问题,可以消除轻微的移动或震动对轴值的影响。
- Sensitivity:轴值的灵敏度,用于控制轴值的变化速度。例如,如果Sensitivity属性设置为2,则每按下一次控制键,轴值将增加2,而不是1。这可以使物体的移动更快或更缓慢。
- Snap:如果勾选,存在一个反方向的输入,则会跳到中点并再沿这个反方向移动;如果不勾选,则不存在一个跳变(snap)的过程。例如人物移动,可以勾选,但赛车类游戏则可以不勾选。
float axisX;
// Update is called once per frame
void Update()
{
axisX = Input.GetAxis("Horizontal");
this.transform.position = new Vector3(axisX*2,1,0);
}
键值的含义
用的chatgpt回答的…
md google is dead
键名称命名约定:
键系列 | 命名约定 |
---|---|
字母键 | a, b, c… |
数字键 | 1, 2, 3… |
箭头键 | up, down, left, right |
小键盘按键 | [1], [2], [3], [+], [equals]… |
修饰键 | right shift, left shift, right ctrl, left ctrl, right alt, left alt, right cmd, left cmd |
特殊键 | backspace, tab, return, escape, space, delete, enter, insert, home, end, page up, page down |
功能键 | f1, f2, f3… |
我这里插一句,这里可以让chatgpt把表格内容生成markdown形式,但由于浏览器会直接渲染成表格,无法复制源文本,可以让它用代码格式展示答案:
键盘输入
静态函数
GetKey
public static bool GetKey (string name); 在用户按下 name 标识的键时返回 true。
Input.GetKey("up")
GetButton
public static bool GetButton (string buttonName); bool 当按下并且未释放轴时,返回 true。(需要输入管理器进行控制)
Input.GetButton("Fire1")
KeyCode
KeyCode其中列出了所有的按键、鼠标和游戏杆选项 (属于Enum)
包含内容参考官方 API
bool key;
// Update is called once per frame
void Update()
{
// key = Input.GetKey(KeyCode.Space);
// key = Input.GetKey("space");
key = Input.GetButton("Jump");
if(key)
transform.localScale = new Vector3(2,2,2);
else
transform.localScale = new Vector3(1,1,1);
}
GetButton/Down/up
GetButton 当按住 buttonName 标识的虚拟按钮时,返回 true。
GetButtonDown 在用户按下由 buttonName 标识的虚拟按钮的帧期间返回 true。
GetButtonUp 在用户释放由 buttonName 标识的虚拟按钮的第一帧返回 true。
GetAxis
返回由 axisName 标识的虚拟轴的值。
对于键盘和游戏杆输入设备,该值将处于 -1…1 的范围内。
该值的含义取决于输入控制的类型,例如,对于游戏杆的水平轴,值为 1 表示游戏杆向右推到底,值为 -1 表示游戏杆向左推到底;值为 0 表示游戏杆处于中性位置。
如果将轴映射到鼠标,该值会有所不同,并且不会在 -1…1 的范围内。此时,该值为当前鼠标增量乘以轴灵敏度。通常,正值表示鼠标向右/向下移动,负值表示鼠标向左/向上移动。
该值与帧率无关;使用该值时,您无需担心帧率变化问题。
float axisX;
float axisY;
// Update is called once per frame
void Update()
{
axisX = Input.GetAxis("Horizontal");
axisY = Input.GetAxis("Vertical");
this.transform.position = new Vector3(axisX*2,axisY*2,0);
}
GetAxisRaw 返回由 axisName 标识的虚拟轴的值(未应用平滑过滤)。
对于键盘和游戏杆输入,该值将处于 -1…1 的范围内。 由于未对输入进行平滑处理,键盘输入将始终为 -1、0 或 1。 如果您想自己完成键盘输入的所有平滑处理,这非常有用。
鼠标输入与控制
OnMouseDown (继承自MonoBehavior)
Rigidbody rigidbody;
private void OnMouseDown() {
rigidbody = this.GetComponent<Rigidbody>();
rigidbody.useGravity = true;
rigidbody.isKinematic = false;
rigidbody.AddForce(-Vector3.forward*10f,ForceMode.Impulse);
Debug.Log("OnMouseDown");
}
Physics.Raycast
public static bool Raycast (Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask, QueryTriggerInteraction queryTriggerInteraction);
返回 bool
当光线与任何碰撞体相交时,返回 true,否则返回 false。
也可以输入一个Ray类 Ray myRay = new Ray(vector3 origin,Vector3 direction);
Physics.Raycast(myRay,RaycastHit hitInfo,float distance,int LayerMask);
参数
- origin 射线在世界坐标系中的起点。
- direction 射线的方向。
- hitInfo 如果返回 true,则 hitInfo 将包含有关最近的碰撞体的命中位置的更多信息。(另请参阅:RaycastHit)。
- maxDistance 射线应检查碰撞的最大距离。
- layerMask 层遮罩,用于在投射射线时有选择地忽略碰撞体。
- queryTriggerInteraction 指定该查询是否应该命中触发器。
描述
向场景中的所有碰撞体投射一条射线,该射线起点为 origin
,朝向 direction
,长度为 maxDistance
。
您可以选择提供一个 LayerMask,以过滤掉不想生成与其碰撞的碰撞体。
您可以通过指定 queryTriggerInteraction 来控制是让触发碰撞体生成命中效果,还是使用全局 Physics.queriesHitTriggers 设置。
实例1 ray检测实现坠落开伞
目标:物体自由降落,当距离地面一定距离时,打开降落伞(没学动画,用active代替),并减速,到达地面收起降落伞。
public GameObject parachute;//降落伞
bool deployed =false;//默认降落伞折叠
public float rayDistance = 4;//射线检测距离
public float dragValue = 6f;//降落伞阻力
void Awake()
{
parachute.SetActive(false);
}
void Update()
{
Ray testRay = new Ray(transform.position,Vector3.down);
RaycastHit hitInfomation;
if(!deployed){
if(Physics.Raycast(testRay,out hitInfomation,rayDistance)){
Deploy();
}
}
}
void Deploy(){
deployed = true;
GetComponent<Rigidbody>().drag = dragValue;
parachute.SetActive(true);
}
void OnCollisionEnter(Collision other) {
parachute.SetActive(false);
}
注意事项:
- rigidBody已过时,用GetComponent< Rigidbody>()代替
- child绑定到cube
实例2 利用ray实现鼠标点击检测
public Camera mCamera;
// Update is called once per frame
void Update()
{
// 检测鼠标按下,0左键,1右键,2中键
if(!Input.GetMouseButtonDown(0)){
return;
}
// Input.mousePosition鼠标的位置信息,左下角(0,0,0)
// Space空间类型:world space、screen space、viewport space
// 将screen坐标转换成世界坐标的射线
Ray r = mCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(r,out hit,1000f))
{
if(hit.collider.tag == "c1"){
Debug.Log("点击上喽") ;
}
}
}
效果跟之前OnMouseDown差不多
实例3 鼠标拖动场景物体
public Camera mCamera;
private void OnMouseEnter() {
transform.localScale = new Vector3(
transform.localScale.x*1.5f,
transform.localScale.y*1.5f,
transform.localScale.z*1.5f
);
}
private void OnMouseExit() {
transform.localScale = new Vector3(
transform.localScale.x/1.5f,
transform.localScale.y/1.5f,
transform.localScale.z/1.5f
);
}
private void OnMouseOver() {
transform.Rotate(Vector3.up,45*Time.deltaTime,Space.Self);
}
private void OnMouseDrag() {
moveObject();
}
void moveObject(){
Ray r = mCamera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if(Physics.Raycast(r,out hit,1000f)){
this.transform.position = new Vector3(
hit.point.x,
hit.point.y,
hit.point.z
);
}
Debug.DrawLine(r.origin,hit.point);
}
如下图所示,能实现鼠标enter变大 离开变小 over旋转,但并没有想要drag效果,因为Raycast也会见到到cube本身,所以可以添加mask,排除cube
// 改用包含mask的Raycast方法
if(Physics.Raycast(r,out hit,1000f,1)){
this.transform.position = new Vector3(
hit.point.x,
hit.point.y+0.5f,
hit.point.z
);
}
还可以固定cube景深
void moveObjectFixDepth(){
Vector3 mouseScreen = Input.mousePosition;
mouseScreen.z = depth;
Vector3 mouseWorld = mCamera.ScreenToWorldPoint(mouseScreen);
this.transform.position = mouseWorld;
}
其他输入
如遥感、触屏省略
还有input system package好像,以后遇到再补充吧
小结
耗时两天,中间两天没学习,忙着玩青藤,心有些浮躁,自我批评下。