[英]How to check whether a key is clicked Unity
I have a teleport orb in my game that you can hover over and click e to use to teleport to, however when I hold my e button down and hover over the orb it teleports me anyways, I want to make it so you have to hover over the orb and click e to teleport not so you can hold e and then hover over it.我的游戏中有一个传送球,你可以通过 hover 并单击 e 用于传送到,但是当我按住我的 e 按钮并在球上 hover 时它无论如何都会传送我,我想做它所以你必须 ZE0132F579DF8E8138ADE69F8F5310BF2Z在球体上方并单击 e 进行传送,而不是这样您就可以按住 e ,然后按住 hover 。 Any ideas on how to do this?
关于如何做到这一点的任何想法?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class IsLookingAtTeleport : MonoBehaviour
{
public AudioSource teleportsound;
public Rigidbody rb;
void Start()
{
}
void FixedUpdate()
{
// Bit shift the index of the layer (8) to get a bit mask
int layerMask = 1 << 8;
// This would cast rays only against colliders in layer 8.
// But instead we want to collide against everything except layer 8. The ~ operator does this, it
//inverts a bitmask.
layerMask = ~layerMask;
RaycastHit hit;
// Does the ray intersect any objects excluding the player layer
if (Input.GetKey("e"))
{
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity, layerMask))
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * hit.distance, Color.yellow);
Debug.Log("Did Hit");
if (hit.transform.tag == "TeleportOrb")
{
Debug.Log("Hit Teleportable Orb");
teleportsound.Play();
rb.transform.position = hit.transform.position;
Destroy(hit.transform.gameObject); // destroy the object hit
}
}
else
{
Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 1000, Color.white);
Debug.Log("Did not Hit");
}
}
}
}
Input.GetKey
is fired every frame while the key stays pressed. Input.GetKey
在按键保持按下状态时每帧都会触发。
What you rather want to use is Input.GetKeyDown
which is true
only in the one frame when the button is actually pressed down.您更愿意使用的是
Input.GetKeyDown
,它仅在实际按下按钮时的一帧中为true
。
Further note that instead of the stringed version I would always go for the ones using KeyCode
as parameter.进一步注意,对于使用
KeyCode
作为参数的版本,我总是使用 go 而不是字符串版本。
And then make sure you do your user Input in Update
not in FixedUpdate
.然后确保您在
Update
而不是FixedUpdate
中进行用户输入。 While the later might work in some cases for getting continous inputs such as GetKey
you might miss single event inputs.虽然后者在某些情况下可能适用于获取连续输入,例如
GetKey
,但您可能会错过单个事件输入。
And finally whenever a Rigibody
is invoved you do not want to set anything through the Transform
component.最后,每当涉及
Rigibody
时,您都不想通过Transform
组件进行任何设置。
// Rather configure the desired layers you want to hit here
// via the Inspector in Unity!
// actually way better than just including everything rather only
// select these layers that actually should be considered as teleport targets
// This way you wouldn't even need to check for Tags!
// just rather place all your teleport objects on a Teleport layer
// and only use a raycast on that layer
// see https://docs.unity3d.com/Manual/Layers.html
[serializeField] private LayerMask hitLayers;
private void Update()
{
if (Input.GetKeyDown(KeyCode.E))
{
// store the ray once
var ray = new Ray(rigibody.position, rigidbody.rotation * Vector3.forward);
if (Physics.Raycast(ray , out var hit, Mathf.Infinity, hitLayers))
{
Debug.DrawRay(ray.origin, ray.direction * hit.distance, Color.yellow);
Debug.Log("Did Hit");
// Rather use CompareTag instead of string based ==
if (hit.gameObject.CompareTag("TeleportOrb"))
{
Debug.Log("Hit Teleportable Orb");
teleportsound.Play();
rb.position = hit.transform.position;
// destroy the object hit
Destroy(hit.gameObject);
}
}
else
{
Debug.DrawRay(ray.origin, ray.direction * 1000, Color.white);
Debug.Log("Did not Hit");
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.