【游戏开发】unity教程3 游戏对象与图形基础 牧师与魔鬼动作分离版

github传送门:https://github.com/dongzizhu/unity3DLearning

Fantasy Skybox FREE的使用

首先我们在Asset Store下载好Fantasy Skybox Free,然后import。

接着只需要在materials文件夹中创建一个新的material,然后将其shader选择成Skybox/6 sided,然后对六个方向分别选择对应位置的图片即可。

接下来直接点击运行既可以看到我们天空盒的效果。

 

总结游戏对象的使用

游戏对象是面向对象变成思想的一种发展,在Unity3D里,每一个游戏中用到的单位都可以是一个游戏对象,然后通过统一的方式来管理。游戏对象可以是unity自带的正方体、球体等三维物体,甚至camera也可以是游戏对象;每个游戏对象都有属性和组件,其中最重要的属性就是transform,用来管理其位置,然后组件可以是脚本,来实现该游戏对象的行为逻辑,也可以是纹理材质等,来完善游戏的画面。通过这样的方式,游戏的运行被强行解耦合,是代码逻辑更加清晰,也是所有的对象和行为更加便于管理。

 

牧师与魔鬼动作分离版

设计一个裁判类,当游戏达到结束条件时,通知场景控制器游戏结束。

我们直接在上次的代码上进行改进。增加一个动作管理器来管理船和人物的移动,然后增加一个Referee类,来判别是否结束当前游戏。在之前的MVC模型中,我们直接由一个Movable类来管理移动的代码,然后在两种对象中写出了相应的方法;这次要实现所谓动作分离,就是指将管理动作的部分从这些controller中分离,单独抽象出来,其实就是将movable进一步抽象,变成一个MoveController的感觉。所以原本是有controller直接调用model的方法来管理action,现在转为调用ActionManager中的相应代码。

Referee也是类似的感觉,直接将原本的check()分离出来形成一个referee类即可。

ActionController的核心部分是继承了SSActionManager的ActionManager类。

public class ActionManager : SSActionManager
{   
    public void MoveBoat(BoatController boatCtrl) {
        SSMoveToAction action;
        Vector3 from = new Vector3(5, 1, 0);
        Vector3 to = new Vector3(-5, 1, 0);
        float speed = 50;

        if (boatCtrl.get_to_or_from() == -1) 
            action = SSMoveToAction.GetSSMoveToAction(from, speed);
        else action = SSMoveToAction.GetSSMoveToAction(to, speed);
        boatCtrl.set_to_or_from();
        AddAction(boatCtrl.getGameobj(), action, this);
    }

    public void MoveCharacter(MyCharacterController itemCtrl, Vector3 finalDes) {
        float time = 3;
        float g = -3;
        Vector3 v0;
        float vy_ByGravity = 0;
        float stepTime = 0.1f;
        Vector3 currentDes = itemCtrl.getPosition();

        List<SSAction> divide = new List<SSAction>();

        // the des here is the final destination
        v0 = new Vector3((finalDes.x - itemCtrl.getPosition().x) / time,
            (finalDes.y - itemCtrl.getPosition().y) / time - 0.5f * g * time, (finalDes.z - itemCtrl.getPosition().z) / time);


        // divide the curve to many parts
        for (int i = 0; i < time / stepTime - 1; i++) {
            // change the vy
            vy_ByGravity += g * stepTime;
            // set current des
            currentDes += v0 * stepTime;
            currentDes.y += vy_ByGravity * stepTime;
            // get the current speed
            float currentSpeed = Mathf.Sqrt(v0.x * v0.x + (v0.y + vy_ByGravity) * (v0.y + vy_ByGravity));
            // add one of the movements
            SSAction temp = SSMoveToAction.GetSSMoveToAction(currentDes, currentSpeed * 10);
            divide.Add(temp);
        }
        SSAction seqAction = SequenceAction.GetSequenceAction(1, 0, divide);
        AddAction(itemCtrl.getGameobj(), seqAction, this);
    }
}

其余的部分大多照抄ppt上的代码就行,这里就不一一贴出了,具体请见github项目。然后就是Referee类,我们让其也在boat上进行实例化。

public class Referee {
		
		private BoatController boat;

		public Referee(BoatController b){
			boat = b;
		}
		
		
		public int Check(CoastController fromCoast, CoastController toCoast, BoatController boat)
		{
			int from_priest = 0;
			int from_devil = 0;
			int to_priest = 0;
			int to_devil = 0;

			int[] fromCount = fromCoast.getCharacterNum ();
			from_priest += fromCount[0];
			from_devil += fromCount[1];

			int[] toCount = toCoast.getCharacterNum ();
			to_priest += toCount[0];
			to_devil += toCount[1];

			if (to_priest + to_devil == 6)		// win
				return 2;

			int[] boatCount = boat.getCharacterNum ();
			if (boat.get_to_or_from () == -1) {	// boat at toCoast
				to_priest += boatCount[0];
				to_devil += boatCount[1];
			} else {	// boat at fromCoast
				from_priest += boatCount[0];
				from_devil += boatCount[1];
			}
			if (from_priest < from_devil && from_priest > 0) {		// lose
				return 1;
			}
			if (to_priest < to_devil && to_priest > 0) {
				return 1;
			}
			return 0;			// not finish
		}
	}

这里我还添加了天空盒,最终的实现效果如图所示。因为游戏过程和之前的版本一样,只是代码的架构稍有变化,所以这里就不再上传一个视频了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值