【unity实战】基于权重的随机事件(附项目源码)

前言

随机功能和UnityEvent前面其实我们都已经做过了,但是随机+UnityEvent事件要怎么使用呢?这里就来举一个例子说明。

当然对之前随机功能和UnityEvent事件感兴趣的小伙伴也可以去看看,这里我贴出地址

ps:本篇为自己的学习记录,希望对你有帮助

开始

一、简单的使用

新增ChestInteractableEvents,定义宝箱交互事件

[System.Serializable]
public class ChestInteractableEvents
{
    [Header("宝箱事件名称")]
	public string EventName;
	[Range(0f, 1f), Header("掉落几率")]
	public float DropChance = 0.5f;
    [Header("宝箱交互事件")]
	public UnityEvent ChestInteractionEvent;
}

新增Box

public class Box : MonoBehaviour
{
	[Header("宝箱交互事件数组")]
	[SerializeField] private ChestInteractableEvents[] _chestInteractionEvents;
	
	//测试执行
	private void Update()
	{
	    if (Input.GetKeyDown(KeyCode.Space))
	    {
	        DetermineAndFireChestEvent();
	    }
	}
	
	private void DetermineAndFireChestEvent()
	{
		// 计算总的掉落几率
		float totalChance = 0f;
		foreach (ChestInteractableEvents interactableEvents in _chestInteractionEvents)
		totalChance += interactableEvents.DropChance;
		
		float rand = Random.Range(0f, totalChance); // 生成一个随机数,范围是0到总掉落几率
		float cumulativeChance = 0f;
		foreach (ChestInteractableEvents interactableEvents in _chestInteractionEvents)
		{
		    cumulativeChance += interactableEvents.DropChance;
		    if (rand < cumulativeChance)
		    {
		        interactableEvents.ChestInteractionEvent.Invoke(); // 触发宝箱交互事件
		        return;
		    }
		}
	}
	
	// 生成金币
	public void SpawnCoins()
	{
		Debug.Log("生成了一个金币");
	}
	
	// 生成敌人
	public void SpawnEnemies()
	{
		Debug.Log("生成了敌人");
	}
	
	// 生成生命药水
	public void SpawnHealthPotion()
	{
		Debug.Log("生成了一个生命药水");
	}
}

箱子挂载脚本,配置事件
在这里插入图片描述
运行效果
在这里插入图片描述

二、完善各种事件

1. 完善生成金币事件

[Header("生成金币")]
[SerializeField] private Rigidbody2D _coinToSpawn; // 要生成的金币刚体
[SerializeField] private int _numberofCoinsTospawn = 100; // 要生成的金币数量
[SerializeField] private float _explosionForce = 10f; // 金币爆炸力度
[SerializeField, Range(0f, 0.5f)] private float _explosionArc = 0.5f; // 金币爆炸角度范围
[SerializeField] private bool _delayBetweenspawns = false; // 是否延迟生成金币
[SerializeField] private Transform _spawnTransform; // 生成金币的位置

/// <summary>
/// 生成金币
/// </summary>
public void SpawnCoins()
{
	if (!_delayBetweenspawns)
	{
		// 直接生成金币
		for (int i = 0; i < _numberofCoinsTospawn; i++)
		{
			Rigidbody2D coinRB = Instantiate(_coinToSpawn, _spawnTransform.position, Quaternion.identity);
			Explosion(coinRB);
		}
	}
	else
	{
		// 延迟生成金币
		StartCoroutine(SpawnCoinsWithDelay());
	}
}

/// <summary>
/// 延迟生成金币
/// </summary>
/// <returns></returns>
private IEnumerator SpawnCoinsWithDelay()
{
	for (int i = 0; i < _numberofCoinsTospawn; i++)
	{
		Rigidbody2D coinRB = Instantiate(_coinToSpawn, _spawnTransform.position, Quaternion.identity);
		Explosion(coinRB);
		yield return null;
	}
}

/// <summary>
/// 金币爆炸效果
/// </summary>
/// <param name="rb"></param>
private void Explosion(Rigidbody2D rb)
{
	Vector2 randDir = new Vector2(Random.Range(-_explosionArc, _explosionArc), 1f);
	Vector2 force = randDir.normalized * _explosionForce;
	rb.AddForce(force, ForceMode2D.Impulse);
}

效果,金币飞出
在这里插入图片描述

2. 完善生成敌人事件敌人

[Header("生成敌人")]
[SerializeField] private GameObject[] _enemiesToSpawn; // 要生成的敌人数组
[SerializeField] private GameObject _enemySpawnParticles; // 敌人生成时的粒子效果
[SerializeField] private int _numofEnemiesToSpawn = 3; // 要生成的敌人数量
[SerializeField, Range(0f, 15f)] private float _enemySpawnoffset = 2f; // 敌人生成的偏移距离

/// <summary>
/// 生成敌人
/// </summary>
public void SpawnEnemies()
{
    for (int i = 0; i < _numofEnemiesToSpawn; i++)
    {
        int randIndex = Random.Range(0, _enemiesToSpawn.Length);
        float randX = Random.Range(-_enemySpawnoffset, _enemySpawnoffset);
        float randY = Random.Range(-_enemySpawnoffset, _enemySpawnoffset);
        Vector2 spawnPos = ((Vector2)_spawnTransform.position + new Vector2(randX, randY)).normalized;
        GameObject enemy = Instantiate(_enemiesToSpawn[randIndex], spawnPos, Quaternion.identity);
        //生成粒子效果
        GameObject enemySpawnParticles = Instantiate(_enemySpawnParticles, spawnPos, Quaternion.identity);
       	//粒子效果和敌人大小一致
       	enemySpawnParticles.transform.localScale = enemy.transform.localScale;
    }
}

效果
在这里插入图片描述

3. 完善生成药水事件

[Header("生成生命药水")]
[SerializeField] private Rigidbody2D _healthPotionToSpawn; // 要生成的生命药水刚体
[SerializeField] private float _upwardForce = 5f; // 生命药水向上的力度

/// <summary>
/// 生成生命药水
/// </summary>
public void SpawnHealthPotion()
{
    Rigidbody2D rb = Instantiate(_healthPotionToSpawn, _spawnTransform.position, Quaternion.identity);
    Vector2 force = Vector2.up * _upwardForce;
    rb.AddForce(force, ForceMode2D.Impulse);
}

效果
在这里插入图片描述

最终效果

在这里插入图片描述

参考

【视频】https://www.youtube.com/watch?v=UeTlJyBz7h8

源码

https://gitcode.net/unity1/unity-randomevent
在这里插入图片描述

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向宇it

创作不易,感谢你的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值