实例化游戏物体的实例(生成游戏物体)

一、实例1:实例化
1、准备工作:制备预制体,命名。如Circle
2、Create Empty,名字自取。如:CirclePrefab
3、给CirclePrefab添加Test.cs
    public GameObject CirclePrefab; // 预制体变量,用于存储Circle预制体的引用

    // Start is called before the first frame update
    void Start()
    {
        CreateCircle(); // 在游戏开始时调用CreateCircle方法生成物体
    }

    void CreateCircle()
    {
        // 使用Instantiate方法从预制体创建一个新的游戏对象实例
        GameObject newCircle = Instantiate(CirclePrefab);
        
        // 将新创建的物体设置为某个特定位置
        // newCircle.transform.position = new Vector3(x, y, z);
        
        // 让新创建的物体成为当前游戏对象的子物体
        // newCircle.transform.SetParent(this.transform);
    }
4、回到Unity,赋值
二、实例2:随机实例化不同物体

限定时间,限定范围,随机位置,随机生成陷阱内的物体

三、实例3:实例化UI物体,随机显示图片
1、Unity设置

(1) UI-Image,名字自取。如:food,设置图片大小80*80,制成预制体,删除Hierarchy中的food

(2) 选中Canvas,Create Empty。名字自取,如:foodArea

(3) 选中foodArea,按住Alt,选择放大到和Canvas大小相同,添加一个名为"FoodArea"的标签

2、新建foodArea.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class foodArea : MonoBehaviour
{
    public int Xlimit = 35;//X轴的限制范围
    public int Ylimit = 19;
    public int xoffset = 17;//X轴的偏移量
    public GameObject foodPrefab;//预制体的空白图片
    public Sprite[] foodSprites;//存储食物图片的数组(图片用来填装预制体的空白)
    private Transform foodEmpties;//图片位置//存放食物图片的空物体位置
    // Start is called before the first frame update
    void Start()
    {
        // 使用标签查找GameObject
        GameObject foodArea = GameObject.FindWithTag("FoodArea");
        if (foodArea != null)//如果找到了
        {
            foodEmpties = foodArea.transform;//图片位置在foodArea的Transform位置上
                                             //将foodEmpties设置为找到的GameObject的Transform
        }
        else
        {
            Debug.LogError("找不到带有'FoodArea'标签的GameObject");
        }
        CreateFood();
    }
    public void CreateFood()
    {
        // 在限制范围内随机生成食物的X和Y坐标
        int index = Random.Range(0, foodSprites.Length);//从图片数组中随机选择一个索引(在0和图片数量之间)
        GameObject food = Instantiate(foodPrefab);//实例化的预制体(foodPrefab)名字为food
        food.GetComponent<Image>().sprite = foodSprites[index];//设置食物预制体上Image组件的sprite为随机选中的图片
        food.transform.SetParent(foodEmpties, false);//将食物设置为foodEmpties的子物体,并保持其本地位置不变
        int x = Random.Range(-Xlimit + xoffset, Xlimit);
        int y = Random.Range(-Ylimit, Ylimit);
        food.transform.localPosition = new Vector3(x * 25, y * 25, 0);//实例化的物体的本地位置
    }
}
3、赋值
四、实例4:实例化长度随文字数量变化的可拖拽的按钮
1、准备工作:

(1) UI-Button TextMeshPro,名字自取。如TestBtn

(2) Create Empty,名字自取。如:nodesPrefab

(3) 将TestBtn中的文字和按钮拆分,并设置为nodesPrefab的子物体

(4) Text(TMP)的额外设置

**Raycast:**用户点击或触摸屏幕时,由摄像机的位置发出的一条射线。

这条射线起点是摄像机的位置,它连到被点击的屏幕的位置并发射到场景中的无限远

Unity会对这条射线与场景中的所有物体进行碰撞检测(物体是否与射线相交)。并根据碰撞结果触发相应的事件(如点击按钮、拖动滑动条等)

**Raycast Target:**用于设置该文本是否可以成为射线投射(Raycast)的目标

勾选时,可被检测到,可设置触发相应事件

不勾选时:无交互事件(无交互事件的时候不要勾选)

2、设置按钮长度随文本字数改变

(1) 新建Nodes.cs

(2) 在nodesPrefab上添加Nodes.cs

using System.Collections;
using System.Collections.Generic;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;

public class Nodes : MonoBehaviour
{
    public GameObject nodeBtn;//在Unity中声明并指定nodeBtn是哪个物体
    public TextMeshProUGUI nodeTitle;
    // Start is called before the first frame update
    void Start()
    {
        //Debug.Log(nodeTitle.text.Length);//测试能否获取文本长度

        if (nodeBtn != null)//如果nodeBtn已被赋值
        {
            Transform nodeTrans = nodeBtn.transform;  //把nodeBtn的Transform,赋值给nodeTrans变量
            RectTransform nodeRect = nodeBtn.GetComponent<RectTransform>();//获取nodeBtn的RectTransform
            if (nodeRect != null)
            {
                int widthNodeBtn = nodeTitle.text.Length*25+30;//按钮的宽度等于文本的长度*25 + 30
                nodeRect.sizeDelta = new Vector2(widthNodeBtn, 30);//按钮的宽,高
                Debug.Log(nodeRect.sizeDelta);//测试是否获取了nodeBtn的RectTransform中的size
            }
            else
            {
                Debug.LogError("无法从nodeBtn获取RectTransform组件");
            }
        }
        else
        {
            Debug.LogError("nodeBtn不存在");
        }
    }
}
3、设置按钮可拖拽

(1) 打开Nodes.cs

public Vector2 dragOffset; // 存储拖拽偏移量


public void OnMouseDown()
    {
        // 当鼠标按下时,计算偏移量
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);//将鼠标屏幕坐标转换成世界坐标
        dragOffset = new Vector2(worldPos.x, worldPos.y) - (Vector2)this.transform.position;//偏移量=世界坐标-当前物体所在的位置
    }
public void OnMouseDrag()
    {
        Debug.Log("拖拽事件");

        // 将鼠标的屏幕坐标转换为世界坐标
        Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);

        // 计算新的位置(考虑偏移量)
        Vector2 newPosition = new Vector2(worldPos.x, worldPos.y) - dragOffset;

        // 更新物体的位置
        this.transform.position = new Vector2(newPosition.x, newPosition.y);
    }

(2) 回到Unity,选中Button,添加Event Trigger组件,并赋值

4、把nodesPrefab制成预制体,并在Hierarchy面板上删除该预制体
5、实例化按钮物体

(1) 新建Test.cs,挂载到Hierarchy界面上的物体上,如:Canvas上

(2) 打开Test.cs

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

public class Test : MonoBehaviour
{
    public Nodes node;//
    // Start is called before the first frame update
    void Start()
    {
        CreateNode();//游戏开始运行时生成Node物体
    }

    public void CreateNode()
    {
        //Debug.Log("测试创建物体");
        Instantiate(node,this.transform);//node:原型(模板);this.transform:克隆出来的物体是挂载物体的子物体
    }
}
五、实例5:在实例4的基础上,实例化文本不同的按钮

1、

相关推荐
吃汤圆的抹香鲸2 小时前
Rider 安装包 绿色版 Win/Mac/Linux 适合.NET和游戏开发者使用 2025全栈开发终极指南:从零配置到企业级实战
linux·运维·windows·sql·游戏·macos·.net
放氮气的蜗牛7 小时前
C++游戏开发系列教程之第二篇:面向对象编程与游戏架构设计
游戏
tekin8 小时前
基于 Python 开发在线多人游戏服务器案例解析
服务器·python·游戏·在线多人游戏服务器
Bluesonli9 小时前
第 22 天:多线程开发,提高 UE5 性能!
学习·游戏·ue5·虚幻引擎·unreal engine
Imagination官方博客19 小时前
Imagination DXTP GPU IP:加速游戏&AI应用,全天候畅玩无阻
人工智能·游戏
若苗瞬1 天前
音乐游戏Pump It Up(PIU)模拟器
游戏·模拟器·音乐游戏·跳舞机·piu
Thomas_YXQ1 天前
Unity3D 战斗系统架构与设计详解
开发语言·unity·架构·系统架构·unity3d
Nicole Potter1 天前
内存泄漏指什么?常见的内存泄漏有哪些?
开发语言·游戏·unity·面试·c#
Jditinpc1 天前
Unity FBXExport导出的FBX无法在Blender打开
unity·游戏引擎·blender
努力的小钟2 天前
lua-游戏红点提示系统抽象设计
游戏·lua