Unity2D学习记录第五期

本文分享了Unity2D游戏开发中的几个实用技巧,包括敌人的简单AI移动、动画事件的使用、对象调用实现的消失动画、父子类的设计及应用,以及通过这些技术制作小游戏的经验总结。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unity2D学习记录第五期


一、敌人的简单AI移动

在这里插入图片描述
首先需要建立两个新的空对象,这里用的方法是在frog下生成子对象但实际上可能另外生成两个对象会好一点,但这样做也有好处,可以方便之后的敌人的左右对象区分,对象的数量也不会有那么多,可能有些人就会想既然是子对象那么青蛙移动的时候点也会移动啊,好像没有什么价值,下面会介绍一个函数可以切断两者的联系,这样就可以达到目的了。
ps:介绍一下怎么弄这个文字标签,在对象面板的左上角处
下面贴上青蛙的移动代码:

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

public class Enemy_FrogController : MonoBehaviour
{
    // Start is called before the first frame update
    public Rigidbody2D rb;
    public Transform leftpoint, rightpoint;
    private bool FaceToLeft = true;
    public float Speed=3;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        transform.DetachChildren();
    }

    // Update is called once per frame
    void Update()
    {
        Movement();    
    }

    void Movement(){ 
        if(FaceToLeft){
            rb.velocity = new Vector2(-Speed, rb.velocity.y);
            if(transform.position.x < leftpoint.position.x){
                transform.localScale = new Vector3(-1,1,1);
                this.FaceToLeft = false;
            }
        }else{
            rb.velocity = new Vector2(Speed, rb.velocity.y);
            if (transform.position.x > rightpoint.position.x){
                transform.localScale = new Vector3(1, 1, 1);
                FaceToLeft = true;
            }
        }
    }
}


简单来讲就是用DetachChildren()函数来断绝父子关系这样点就不会跟着动,也就实现了移动了

二、动画事件

在这里插入图片描述这个add event就是添加动画事件的地方,简单来说就是一个添加动画执行过程中插入的代码。就举一个图中我使用的例子,想要稳定地使得青蛙能够膨胀一下再跳跃这样子的动作代码就比较难以实现。假设你在青蛙的控制文件中写入了一个jump函数用于控制青蛙的跳跃动画和速度控制,你就可以接在idle动画之后添加一个动画事件来执行jump函数的代码,起跳后落下进入falling状态最后又回到idle状态就能完美实现了。

三、敌人的消失动画(对象调用)

Enemy_Frog frog = collision.gameObject.GetComponent<Enemy_Frog>();
frog.die();

在player的控制文件中使用碰撞到的物体的Enemy_Frog类的对象的die方法,这样的形式来获取并调用,这其中有三件事情要做,踩头后的对象调用,消灭的动画,销毁对象,这就涉及到我上一个说到的东西,你可以自己试试看。
ps:对象调用后不要直接在函数中销毁对象,设置动画逻辑变为销毁的动画后再触发动画事件来销毁。另外对于单向事件动画的属性中可以使用trigger类型而不是bool类型,并且像死亡这样的任意状态均可能转化的动画也可以使用一下any state来减少一些工作量

四、父子类及其调用

ps:第三步没有做完的建议先做完
在类的概念中是有父子关系的,这里先引入一个关键字protected,区别与private只能私人使用的精致的利己主义者和public谁都可以用的共享精神,protected只能父子间使用,好歹知道孔融让梨。
在游戏中是有大量敌人的,总不可能对于每一个敌人通用的一些行为比如说死亡动画和和击退效果等都写一遍代码效率非常低,那么父子类就是一个非常好的选择,下面就给出enemy的父类代码示例:

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

//MonoBehaviour就相当于是所有对象的父类
public class Enemy : MonoBehaviour
{
	//只在父子间共享的方法和属性可以防止代码的误用,下面的两个函数也可以使用这个关键字
    protected Animator Anim;

    protected virtual void Start()
    {
        Anim = GetComponent<Animator>();
    }

    public void die(){
        Anim.SetTrigger("death");
    }

    void delete(){
        Destroy(gameObject);
    }
}

熟悉java的朋友可能知道获取属性的方法是使用getXxx方法,但在这个父子类的unity脚本的场景下有一个更好用的办法就是在子类start方法执行的时候base.Start();方法。
base相当于java中的super也就是调用父类的意思,这样就可以获取父类在start方法中加载出来的属性,后续的代码就和你在第三步做出来的一样

五、小总结

到此为止,目前的内容已经足够开发出一些单场景的小游戏了。当然对于做出一款像模像样的独立游戏还是有很大距离的,希望各位看官能和我一同学习进步下去,共同勉励。

<think>好的,我现在需要回答用户关于Unity2D地形生成或编辑功能的教程和使用方法。用户提到了地形生成和编辑器,可能想了解如何创建动态地形或者使用工具来编辑地形。首先,我应该回忆一下之前提供的引用内容,看看有没有相关的信息可以利用。 引用1提到了使用Polygon Collider 2D来实体化地形,这可能和碰撞体的生成有关。引用2中的山脉脚本展示了如何通过移动和销毁对象来生成动态地形,比如山脉。引用3讨论了挖洞和涂抹地形的方法,特别是碰撞处理。引用4则是关于随机生成物体和地图的简易方法。这些引用都涉及地形生成的不同方面,但需要整合成一个连贯的教程。 用户可能需要基础的步骤,比如手动创建静态地形和使用Tilemap,然后是程序化生成,比如随机地形或无限地形。可能还需要介绍一些优化方法,比如对象池或碰撞体简化。此外,用户可能对工具如ProBuilder或第三方编辑器感兴趣,但引用中没有提到,可能需要结合通用知识。 需要确保回答结构清晰,分步骤说明,并且每个部分都提供具体的实现方法或代码示例。例如,手动创建地形可以用Tilemap,程序化生成可以用Perlin噪声,动态地形可以用移动的预制体。同时,要引用相关的引用内容,比如引用2的山脉脚本和引用4的随机生成。 可能还需要注意LaTeX格式的正确使用,但问题中数学内容不多,可能涉及坐标或算法时使用。例如,Perlin噪声的算法可以简要提及,但不需要深入数学公式。此外,生成相关问题时要围绕地形生成的扩展,比如优化、不同地形类型、性能问题等。 最后,确保回答使用中文,代码示例正确,引用标记自然。可能需要检查是否有遗漏的部分,比如地形编辑器的使用方法,如果引用中没有,可能需要简要提及官方工具或第三方资源,但避免推测不存在的信息。</think>以下是Unity2D地形生成与编辑功能的实现教程,结合了基础方法和进阶技巧: ### 一、基础地形创建 1. **手动创建静态地形** - 使用Tilemap系统绘制地形: ```csharp // 在编辑器中选择 Window > 2D > Tile Palette 创建瓦片调色板 // 通过画笔工具直接在地图上绘制 ``` - 添加碰撞体:为地形添加$Composite Collider 2D$组件,自动合并碰撞形状[^1] 2. **程序化生成地形** - 使用Perlin噪声生成随机高度图: ```csharp public GameObject terrainPrefab; void GenerateTerrain() { for(int x=0; x<100; x++){ float y = Mathf.PerlinNoise(x * 0.1f, 0) * 10; Instantiate(terrainPrefab, new Vector3(x, y), Quaternion.identity); } } ``` - 动态生成无限地形(引用2方法扩展): ```csharp public class TerrainGenerator : MonoBehaviour { public GameObject[] terrainChunks; public float spawnInterval = 5f; void Start() { InvokeRepeating("SpawnChunk", 0, spawnInterval); } void SpawnChunk() { int index = Random.Range(0, terrainChunks.Length); Instantiate(terrainChunks[index], transform.position, Quaternion.identity); } } ``` ### 二、高级地形编辑 1. **动态地形修改**(引用3原理实现) - 挖洞功能实现步骤: 1. 创建多边形碰撞体记录地形轮廓 2. 使用射线检测获取鼠标点击位置 3. 修改多边形顶点数据实现"挖除"效果 ```csharp PolygonCollider2D collider; void Update() { if(Input.GetMouseButton(0)){ Vector2 mousePos = Camera.main.ScreenToWorldPoint(Input.mousePosition); collider.pathCount = ModifyCollider(collider, mousePos); } } ``` 2. **地形笔刷系统** - 实现地形涂抹功能: ```csharp public float brushSize = 1f; void PaintTerrain(Vector2 center) { Collider2D[] hits = Physics2D.OverlapCircleAll(center, brushSize); foreach(var hit in hits){ if(hit.CompareTag("Terrain")){ hit.GetComponent<Tilemap>().SetTile(hit.transform.position, selectedTile); } } } ``` ### 三、优化策略 1. 使用对象池管理地形块(引用4方法扩展) ```csharp public class ObjectPool : MonoBehaviour { public GameObject prefab; public int poolSize = 10; private Queue<GameObject> pool = new Queue<GameObject>(); void Start() { for(int i=0; i<poolSize; i++){ GameObject obj = Instantiate(prefab); obj.SetActive(false); pool.Enqueue(obj); } } public GameObject GetObject() { if(pool.Count > 0){ GameObject obj = pool.Dequeue(); obj.SetActive(true); return obj; } return Instantiate(prefab); } } ``` 2. 碰撞体优化:定期调用`collider.usedByComposite = true`更新复合碰撞体[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值