emm关于聊天功能的闲话
聊天功能也是使用PhotonChat提供的API,比较方便的是参考demo,发消息的逻辑代码直接拿来用就好了。要注意目前pun版本的chat服务只有eu服务器。
然后本项目的聊天功能中UI是自主开发的。仿照英雄联盟的聊天样式,游戏内不会遮挡,并且一定时间没有消息后自动隐藏…
道具战游戏简介
部分资源是Unity官方商店(比如人物)、还有部分资源来自其他素材网站。
截图
生成角色。

随着时间场上生成了不少道具。

捡了一个隐身、导弹、地雷,还有瞬移突进技能。

按2发射导弹打坏木箱,附带粒子特效。

游戏功能
人物–控制系统、生命值系统、道具捡拾与使用系统。
整个场景–道具生成系统(道具悬浮效果)、草丛隐身机制。
道具–不同道具不同功能,其中有隐身道具要和草丛的隐身联动起来。
道具计划制作五个(导弹、地雷、恢复、隐身、疾步),额外制作一个冲刺位移技能。
其中隐身道具和进入草丛“隐身”的实现方式详见下一篇文章。
生成数有最大限制以控制游戏以适中的节奏进行,同时避免过多道具占用cpu资源。
但是currentCount的–有问题,不清楚原因。
关键代码
全局
PropsManager.cs:场景中道具生成器。
/// <summary>
/// 控制道具的生成
/// </summary>
public class PropsManager : MonoBehaviour
{
public enum PropsType
{
None,
MissileProp, //炮弹
LandmineProp, //地雷
CloakProp,
HealthBottleProp, //血瓶
SpeedUpProp,//疾步
FlashSkill
}
private string[] propsPrefabNameWithRandom
= {
"DroppedMissile", "DroppedMissile", "DroppedLandMine", "DroppedLandMine", "DroppedBottle", "DroppedRandomBox" };
public static int mapSizeCanSpawn = 20;//default 20,用于随机范围
public float spawnInterval = 4;//间隔:?秒一次
private float currentTime = 4;
public int spawnCountOneTime = 4;
public int maxSpawnCountPermit = 20;//限制最大数量---弱限制,可19到19 + spawnCountOneTime。
private static int currentCountInScene = 0;//当前场景中存在的数量
private void Start()
{
if(!PhotonNetwork.IsMasterClient)
{
return;
}
maxSpawnCountPermit = PhotonNetwork.PlayerList.Length * 15;
}
private void Update()
{
//生成道具
if(PhotonNetwork.IsMasterClient && PropsGameManager.instance.isGameStart)
{
//计时
if(currentTime > 0)
{
currentTime -= Time.deltaTime;
}
else
{
//判断道具数是否到达上限
//if (currentCountInScene < maxSpawnCountPermit)
//{
for (int i = 0; i < spawnCountOneTime; i++)
{
/*
PhotonNetwork.Instantiate(
Const.PUN_PROPS_GAME_PREFABS_BASEPATH
+ propsPrefabNameWithRandom[Random.Range(0, propsPrefabNameWithRandom.Length)]
, propsSpawnPoints[Random.Range(0, propsSpawnPoints.Length)].position
, Quaternion.identity);
*/
Vector3 pos = new Vector3(Random.Range(-18f, 18f), 1, Random.Range(-18f, 18f));
PhotonNetwork.Instantiate(Const.PUN_PROPS_GAME_PREFABS_BASEPATH
+ propsPrefabNameWithRandom[Random.Range(0, propsPrefabNameWithRandom.Length)]
, pos
, Quaternion.identity);
currentCountInScene++;
}
//}
currentTime = spawnInterval;
}
}
}
public static void DecreaseCurrentCount()
{
currentCountInScene--;//TODO:线程是否安全
}
}
悬浮物道具
DroppedProps.cs:掉落物形式的道具(可捡状态,包含悬浮动作、保证生成在空旷处)
public class DroppedProps : MonoBehaviour//用dotween
{
public PropsManager.PropsType propType = PropsManager.PropsType.HealthBottleProp;
private Vector3 startPos;
void Start()
{
if(PhotonNetwork.IsMasterClient)
{
TestCollision();
}
Move();
}
//出生检测
//静止物体没有刚体,通过物理检测来决定重新生成,同修改DroppedRandomProps脚本
private void TestCollision()
{
float radius = 0.8f;
Vector3 explosionPos = transform.position;
Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
foreach (Collider hit in colliders)
{
if (hit.gameObject == this.gameObject)
{
Debug.Log("self collision");
continue;
}
if (hit.gameObject.tag.Equals("Barrier") || hit.gameObject.tag.Equals("WoodenBox")
|| hit.gameObject.tag.Equals("Grass") || hit.gameObject.tag.Equals("DroppedProps"))
{
float sphereRadius = (float)PropsManager.mapSizeCanSpawn;
Vector3 pos = new Vector3(Random.Range(-sphereRadius, sphereRadius), 1, Random.Range(-sphereRadius, sphereRadius));
if(PhotonNetwork.IsMasterClient)
{
Debug.Log("发生碰撞self 刷新");
PhotonNetwork.Instantiate(Const.PUN_PROPS_GAME_PREFABS_BASEPATH + gameObject.name.Replace("(Clone)", ""), pos, Quaternion.identity);
PhotonNetwork.Destroy(gameObject);
return;
}
}
}
}
//悬浮
private void Move()
{
startPos = transform.position;
transform.DOPath(new Vector3[] {
startPos, transform.position + new Vector3(0, 0.5f, 0), startPos }, 2)//Vector3.up//new Vector3(0,0.5f,0)
.SetLoops(-1, LoopType.Restart);
transform.DOBlendableLocalRotateBy(new Vector3(0, 360, 0), 4f, RotateMode.FastBeyond360)//.DORotate(new Vector3(0, 360, 45), 3f, RotateMode.WorldAxisAdd)
.SetLoops(-1, LoopType.Restart);//循环设置为-1为一直
}
//销毁写在人物里面,背包满了道具碰到不销毁
}
DroppedRandomProps.cs:因为隐身和疾步一些道具没有合适的3d资源。统一用一个“问号箱子”,也就是随机道具。
和DroppedProps.cs基本一样,多了一个随机确定被捡的道具。
实际道具
PropMissile.cs:导弹道具(施放道具,非掉落物形式,为玩家使用后的真实导弹物体)
包含碰撞(爆炸)检测。和初始化问题。初始化时主要为调整导弹朝向。
(导弹模型默认导弹头是z轴正向的,所以要把z轴正向转向发射方向)
public class PropMissile : MonoBehaviour
{
public Player Owner {
get; private set; }
public GameObject explosionParticle;
public void Start()
{
Destroy(gameObject, 3.0f);
}
public void OnTriggerEnter(Collider collision)
{
Debug.Log(collision.gameObject.name + "eee");//TODO:有时候会碰到自己?
if (collision.gameObject.tag.Equals("DroppedProps") || collision.gameObject.tag.Equals("Grass"))
{
return;
}
if (collision.gameObject.tag.Equals("Player") && collision.gameObject.GetComponent<PhotonView>().Owner == Owner)
{
return;
}
float radius = 3.0f;
Vector3 explosionPos = transform.position;
Collider[] colliders = Physics.OverlapSphere(explosionPos, radius);
bool clipIsPlayed = false;//如果破坏掉木箱,此bool控制只播放一次音效
foreach (Collider hit in colliders)
{
if (hit.gameObject.tag.Equals("Player"))//打到玩家
{
//TODO:不能打到自己
if(Owner.NickName.Equals(hit.gameObject.GetComponent

最低0.47元/天 解锁文章
1283

被折叠的 条评论
为什么被折叠?



