You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity网球游戏3D盒碰撞异常:勾选IsTrigger仅预运行触发,取消无响应

网球游戏3D碰撞失效问题修复方案

核心问题分析

  • 碰撞回调函数名称错误:你自定义的CollisionTrigger不是Unity官方认可的碰撞/触发回调函数,引擎不会自动调用该方法。
  • 直接修改Transform位置绕过物理引擎:通过transform.position直接修改物体位置会跳过Unity物理系统的碰撞检测逻辑,导致碰撞无法被正确识别。
  • IsTrigger配置与回调不匹配:触发模式和物理碰撞模式对应不同的回调函数,错误的配置会导致碰撞逻辑完全失效。

具体修复步骤

1. 替换为Unity官方回调函数

根据你的需求选择对应回调:

  • 若使用IsTrigger触发模式:使用OnTriggerEnter(Collider other)、OnTriggerStay或OnTriggerExit
  • 若使用物理碰撞模式:使用OnCollisionEnter(Collision collision)、OnCollisionStay或OnCollisionExit

2. 修改物体移动方式(兼容物理引擎)

不要直接修改transform.position,改用Rigidbody的MovePosition方法(适配运动学Rigidbody),确保物理引擎能追踪物体运动状态:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Character : MonoBehaviour
{
    public Leftmove left;
    float speed = 3f;
    float force = 10;
    bool hit;
    public Transform target;
    private Rigidbody rb;
    private Rigidbody targetRb;

    void Start()
    {
        rb = GetComponent<Rigidbody>();
        targetRb = target.GetComponent<Rigidbody>();
        // 玩家和球拍设为运动学,避免被物理力推动
        rb.isKinematic = true;
        targetRb.isKinematic = true;
    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.F))
        {
            hit = true;
        }
        else if (Input.GetKeyUp(KeyCode.F))
        {
            hit = false;
        }

        // 玩家移动逻辑
        if (!hit)
        {
            Vector3 moveDir = Vector3.zero;
            if (Input.GetKey(KeyCode.LeftArrow)) moveDir.x += speed;
            if (Input.GetKey(KeyCode.RightArrow)) moveDir.x -= speed;
            if (Input.GetKey(KeyCode.UpArrow)) moveDir.z -= speed;
            if (Input.GetKey(KeyCode.DownArrow)) moveDir.z += speed;
            
            rb.MovePosition(rb.position + moveDir * Time.deltaTime);
        }
        // 球拍移动逻辑
        else
        {
            Vector3 targetMoveDir = Vector3.zero;
            if (Input.GetKey(KeyCode.LeftArrow)) targetMoveDir.x += speed;
            if (Input.GetKey(KeyCode.RightArrow)) targetMoveDir.x -= speed;
            if (Input.GetKey(KeyCode.UpArrow)) targetMoveDir.z -= speed;
            if (Input.GetKey(KeyCode.DownArrow)) targetMoveDir.z += speed;
            
            targetRb.MovePosition(targetRb.position + targetMoveDir * Time.deltaTime);
        }
    }
}

3. 修正碰撞回调函数示例

触发模式(IsTrigger勾选)回调:

private void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Tennis ball"))
    {
        Vector3 dir = target.position - transform.position;
        other.GetComponent<Rigidbody>().velocity = dir.normalized * force;
    }
}

物理碰撞模式(IsTrigger不勾选)回调:

private void OnCollisionEnter(Collision collision)
{
    if (collision.collider.CompareTag("Tennis ball"))
    {
        Vector3 dir = target.position - transform.position;
        collision.rigidbody.velocity = dir.normalized * force;
    }
}

4. 组件配置要求

  • 触发模式:
    • 网球必须带有非运动学Rigidbody(取消IsKinematic勾选)
    • 玩家/球拍的Collider勾选IsTrigger,可保留运动学Rigidbody
  • 物理碰撞模式:
    • 至少一方(推荐网球)带有非运动学Rigidbody
    • 双方Collider都不勾选IsTrigger

额外注意事项

  • 确认网球的Tag为Tennis ball,大小写完全一致
  • 检查Collider的大小、位置是否与模型匹配,避免碰撞体偏移导致检测失效
  • 物理碰撞模式下,可调整网球Rigidbody的质量、阻力参数优化碰撞反馈

内容的提问来源于stack exchange,提问作者Dramus17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 06:25:23