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

Unity(C#)游戏开发需求:小球撞墙不互撞、白球置红球后方及点击计分

Hey Tommy, let's walk through each of your requirements one by one—this is all straightforward to set up in Unity with C#!

1. Ball-Wall Collisions (No Ball-to-Ball Collisions)

The easiest way to handle this is using Unity's Layer Collision Matrix:

  • First, create two new layers: go to Edit > Project Settings > Tags and Layers, add BallLayer and WallLayer.
  • Assign all your balls to the BallLayer, and all wall objects to WallLayer.
  • Open the Physics settings (same menu as above, go to the Physics tab for 3D, Physics 2D for 2D games). In the Layer Collision Matrix, uncheck the box where BallLayer intersects with itself—this stops balls from colliding with each other. Make sure the box for BallLayer ↔ WallLayer is checked so balls bounce off walls.
  • Add a Rigidbody (3D) or Rigidbody2D (2D) to each ball (enable gravity if you want them to fall, or turn it off for floating movement). Also add a collider component (like SphereCollider or CircleCollider2D) to balls and walls. Walls can use static colliders for better performance.

Unity's physics system will handle the bouncing automatically, but if you want custom behavior (like adjusting bounce force), you can add this script to your balls:

using UnityEngine;

public class BallBounce : MonoBehaviour
{
    [SerializeField] private float bounceForce = 5f;

    private void OnCollisionEnter(Collision collision) // Use OnCollisionEnter2D for 2D
    {
        if (collision.gameObject.layer == LayerMask.NameToLayer("WallLayer"))
        {
            // Add custom bounce logic here if needed
            GetComponent<Rigidbody>().AddForce(collision.contacts[0].normal * bounceForce, ForceMode.Impulse);
        }
    }
}
2. White Balls Appear Behind Red Balls

This is all about render ordering:

For 2D Games:

  • Use Sorting Layers: Go to Edit > Project Settings > Tags and Layers, create two new Sorting Layers: RedBallRender and WhiteBallRender. Drag WhiteBallRender below RedBallRender in the list (lower layers render behind higher ones).
  • Select all red balls, go to their SpriteRenderer component, set the Sorting Layer to RedBallRender. Do the same for white balls, selecting WhiteBallRender. Alternatively, you can just adjust the Order in Layer field—set red balls to 1 and white balls to 0 (higher numbers render on top).

For 3D Games:

  • Adjust the Z-axis position of your balls. If your camera is facing along the Z-axis (common for top-down or side views), set white balls' Z value to be higher than red balls' (e.g., red balls at Z=0, white at Z=1)—this will make whites render behind reds.
3. Click Detection & Score Logic

We can use either OnMouseDown() (simple) or IPointerClickHandler (more flexible for UI integration). Here's a complete script that works for both 2D and 3D:

First, add tags to your balls: create WhiteBall and RedBall tags, then assign them to the respective balls. Then attach this script to every ball (or create a manager script to handle clicks globally—this is simpler for starters):

using UnityEngine;
using UnityEngine.UI;

public class BallScoreHandler : MonoBehaviour
{
    [SerializeField] private Text scoreDisplay;
    private int currentScore = 0;

    // Works for both 2D and 3D if colliders are set up
    private void OnMouseDown()
    {
        if (gameObject.CompareTag("WhiteBall"))
        {
            currentScore++;
            Debug.Log($"Score increased! Current: {currentScore}");
        }
        else if (gameObject.CompareTag("RedBall"))
        {
            currentScore--;
            Debug.Log($"Score decreased! Current: {currentScore}");
        }
        UpdateScoreUI();
    }

    private void UpdateScoreUI()
    {
        if (scoreDisplay != null)
        {
            scoreDisplay.text = $"Score: {currentScore}";
        }
    }
}
  • Don't forget to drag your UI Text element into the scoreDisplay field in the Inspector for each ball, or make currentScore static if you want a single manager script to handle all clicks.

If you prefer using IPointerClickHandler (better if you have UI elements overlapping), add an EventSystem to your scene (right-click in Hierarchy > UI > Event System), and add a PhysicsRaycaster (3D) or Physics2DRaycaster (2D) component to your main camera. Then modify the script to implement the interface:

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class BallScoreHandler : MonoBehaviour, IPointerClickHandler
{
    [SerializeField] private Text scoreDisplay;
    private static int currentScore = 0; // Static so all balls share the same score

    public void OnPointerClick(PointerEventData eventData)
    {
        if (gameObject.CompareTag("WhiteBall"))
        {
            currentScore++;
        }
        else if (gameObject.CompareTag("RedBall"))
        {
            currentScore--;
        }
        UpdateScoreUI();
    }

    private void UpdateScoreUI()
    {
        scoreDisplay?.text = $"Score: {currentScore}";
    }
}

That's all! Each part works independently, so you can test them one by one to make sure everything behaves as expected.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:07:52