- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在使用“Unity in Action”一书时偶然发现了一个问题。在第 3 章结束时,您将了解简单 fps 游戏的基础知识。它基本上是一个简单而小的水平的播放器(连接到它的相机),它只存在于形成墙壁和地板等的许多立方体中。这些立方体上都有盒子对撞机。现在玩家也可以射击移动的敌人,这些敌人也可以射击。这是由 Raycast/RaycastHit 完成的。所有这一切都很完美,所以我想添加一些东西来重新组装弹孔,只需在墙上实例化一个黑色球体对象,火球(这是敌人和玩家射击的对象)击中它。这行得通,但有时火球物体会穿过墙壁。如果它后面有另一堵墙,火球对象会被第二堵墙摧毁,所需的球体会在第二堵墙而不是第一堵墙上创建。
我将火球的速度从 20 更改为 10,然后再更改为 20,速度为 10 时,成功率约为 19/20,而速度为 20 时,成功率约为 6/10。
这是火球的代码,它应该检查它是击中玩家(然后扣除生命值,工作正常)还是击中敌人(然后敌人倒下,也工作正常)或击中墙壁在这种情况下应该创建球体。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Fireball : MonoBehaviour {
public float speed = 10.0f;
public int damage = 1;
[SerializeField] private GameObject wallHit;
private GameObject _wallHit;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
transform.Translate(0,0, speed * Time.deltaTime);
}
void OnTriggerEnter(Collider other){
RaycastHit hit;
PlayerCharacter player = other.GetComponent<PlayerCharacter>();
ReactiveTarget target = other.GetComponent<ReactiveTarget>();
WallBehavior wall = other.GetComponent<WallBehavior>();
if(player != null){
player.Hurt(damage);
}
if(target != null){
target.ReactToHit();
}
if(wall != null){
if(Physics.Raycast(transform.position, transform.forward, out hit)){
wall.WallWasHit(hit);
}
}
Destroy(this.gameObject);
}
}
如您所见,我尝试过为每面墙添加一个 WallBehavior 脚本,如下所示:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WallBehavior : MonoBehaviour {
[SerializeField] private GameObject wallHit;
private GameObject _wallHit;
static int count = 0;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void WallWasHit(RaycastHit hit){
count++;
Debug.Log("Wall was hit: " + count);
_wallHit = Instantiate(wallHit) as GameObject;
_wallHit.transform.position = hit.point;
}
}
但到目前为止,我试图理解为什么这种情况很少发生的尝试都没有成功,我希望有人能帮助我解决这个问题,因为在我继续阅读这本书之前,我觉得这可能对我的学习至关重要!提前致谢。如果需要更多信息,我很乐意提供。请参阅下图以更好地了解问题。
编辑:如答案中所述,我相应地替换了火球脚本,但我不确定如何同样更改以下脚本。这个脚本在我的相机上,它在我的播放器对象上。在 Update 函数中,Fireball 被实例化并进行了移动,所以我猜这会导致问题?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayShooter : MonoBehaviour {
private Camera _camera;
[SerializeField] private GameObject fireballPrefab;
private GameObject _fireball;
void Start () {
_camera = GetComponent<Camera>();
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
void OnGUI(){
int size = 12;
float posX = _camera.pixelWidth/2 - size/4;
float posY = _camera.pixelHeight/2 - size/2;
GUI.Label(new Rect(posX, posY, size, size), "X");
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButtonDown(0)){
Vector3 point = new Vector3(_camera.pixelWidth/2, _camera.pixelHeight/2, 0);
_fireball = Instantiate(fireballPrefab) as GameObject;
_fireball.transform.position = transform.TransformPoint(Vector3.forward * 1.5f);
_fireball.transform.rotation = transform.rotation;
Ray ray2 = _camera.ScreenPointToRay(point);
RaycastHit hit;
if(Physics.Raycast(ray2, out hit)){
GameObject hitObject = hit.transform.gameObject;
ReactiveTarget target = hitObject.GetComponent<ReactiveTarget>();
if(target !=null){
target.ReactToHit();
}
}
}
}
}
最佳答案
这不是移动 Rigidbody
对象的方法,像这样移动它可能会导致很多问题,包括您问题中提到的问题。具有 Rigidbody
的对象应使用 Rigidbody
组件和 Rigidbody.MovePosition
、Rigidbody.AddForce
等函数移动和 Rigidbody.velocity
不是通过 transform
或 transform.Translate
。
此外,您应该在 FixedUpdate
函数而不是 Update
函数中移动 Rigidbody
对象。 如果您要通过变换移动其他 Rigidbody
对象,那么您也必须修复它们。 下面的示例将 transform.Translate
替换为
:Fireball
脚本中的 Rigidbody.MovePosition
public float speed = 10.0f;
public int damage = 1;
[SerializeField]
private GameObject wallHit;
private GameObject _wallHit;
public Rigidbody rb;
// Use this for initialization
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
//Move to towards Z-axis
Vector3 pos = new Vector3(0, 0, 1);
pos = pos.normalized * speed * Time.deltaTime;
rb.MovePosition(rb.transform.position + pos);
}
void OnTriggerEnter(Collider other)
{
RaycastHit hit;
PlayerCharacter player = other.GetComponent<PlayerCharacter>();
ReactiveTarget target = other.GetComponent<ReactiveTarget>();
WallBehavior wall = other.GetComponent<WallBehavior>();
if (player != null)
{
player.Hurt(damage);
}
if (target != null)
{
target.ReactToHit();
}
if (wall != null)
{
if (Physics.Raycast(transform.position, transform.forward, out hit))
{
wall.WallWasHit(hit);
}
}
Destroy(this.gameObject);
}
如果您仍然遇到问题,请改用 Rigidbody.velocity
:
void FixedUpdate()
{
Vector3 pos = Vector3.zero;
pos.z = speed * Time.deltaTime;
rb.velocity = pos;
}
有时,根据对象的大小和它移动的速度,您可能需要将其刚体Interpolate从None设置为Interpolate 和碰撞检测 到连续。
不要忘记删除 Update
函数中的代码。
编辑:
我看了你的项目,发现了新的问题:
1。您在“火球”游戏对象上启用了 IsTrigger。请取消选中对撞机上的 IsTrigger
。
2.你只是想发射一颗子弹。强制应该只添加一次,而不是每个 FixedUpdate
。在 Start
函数而不是 FixedUpdate
函数中添加强制。使用 Rigidbody.velocity
而不是 Rigidbody.MovePosition
。
删除FixedUpdate
函数和其中的代码。
这应该是您的新开始功能:
void Start()
{
rb = GetComponent<Rigidbody>();
Vector3 pos = transform.forward * speed * Time.deltaTime;
rb.velocity = pos;
}
关于c# - Collider 并不总是检测到 OnTriggerEnter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49718869/
我正在尝试通过使用 OnCollisionEnter() 在碰撞时禁用其刚体来制作粘性手榴弹。但是,OnCollisionEnter() 会在明显没有发生碰撞时触发,如您在这张图片中所见:https:
我有一个玩家(球体)和 4 个敌人(胶囊)。所有敌人都添加了角色 Controller 。他们也都有一个子游戏对象,它有一个刚体(没有质量,没有重力)和一个盒子碰撞器。 Box Collider 足够
我正在制作某种 Evolution 模拟游戏。我有一个脚本,应该在生物的 CapsuleCollider 触发 OnTriggerEnter() 时销毁它所附加的 GameObject。 我有一个问题
我目前正在尝试在 Unity 中创建一个 2D 游戏,我的玩家在他的上半部分有一个盒子碰撞器,在他的下半部分有一个圆形碰撞器;这可以平滑坡道和其他东西。 当我收集一颗 gem 时,我的 OnTrigg
public class Storm : MonoBehaviour { [SerializeField] private PlayerVitals playerVitals; [Se
我正在尝试对 2D 角色和对撞机对象进行碰撞。我已经定义了 OnTriggerEnter 函数以在输入触发器时在调试器中显示一条消息。该角色是 Unity 标准 Assets 包中的“Characte
我有一个附在盒子上的脚本,盒子有两个用于物理的碰撞器和一个(稍大一点)用于在我的玩家走过它时检测 OntriggerEnters。我有一个脚本附加到执行以下操作的框: public class Col
所以,我正在尝试进行无限跳线,但出于某种原因,OnTriggerEnter2D 函数 rb2D 给了我一个错误,即使我已尽一切努力使其正常工作(至少我是这么认为的,因为每次我这样做时它都会起作用。)错
我在使用“Unity in Action”一书时偶然发现了一个问题。在第 3 章结束时,您将了解简单 fps 游戏的基础知识。它基本上是一个简单而小的水平的播放器(连接到它的相机),它只存在于形成墙壁
我正在尝试检测在篮球比赛中 throw 戒指的球。我在环上使用以下脚本 public class Anotar : MonoBehaviour { private ControlJuego c
我在简单的弹道学方面遇到了一些问题。由于我是编码新手,而且我浪费了 2 天的时间进行搜索,所以我决定问一个问题。我的 bullet.cs 脚本有问题,代码工作正常,除了跳弹部分。我使用 OnTrigg
我正在尝试让标有“Bullet”的项目符号项目击中此代码所附加的目标。我在项目符号上勾选了 Is Trigger。碰撞在目标上起作用,因为我可以与玩家一起击中它。任何帮助将不胜感激。 void OnT
几个小时以来,我一直在努力寻找解决方案。我正在努力学习,但我一直被困在这个单一的问题上。我有随机移动的红色生物,我希望它们在与绿色物体碰撞时克隆自己。这是附加到绿色对象的脚本。 using Syste
我正在尝试确定播放器何时接地,并且使用桌面播放器,下面描述的方法非常有效,但是当编译到 Android 时表现相当奇怪,我不确定它是否只是延迟或什么,但它正在更新的 bool 很少是它应该是的。 判断
我最近遇到的一个问题如下。 我有一个 Player 对象,上面附加了一个 Player 脚本。 我的游戏对象层次结构看起来像这样: Player (parent) // Has P
好的,所以我看不出我的问题在哪里。我将 OnTriggerEnter 用于我的移动平台。它具有刚体组件,并且在平台和播放器上都将盒子碰撞器设置为 isTrigger,但由于某种原因,当我的平台被播放器
我是一名优秀的程序员,十分优秀!