UNITY作业——游戏对象与图形基础

1、基本操作演练

  • 下载 Fantasy Skybox FREE, 构建自己的游戏场景

下载天空盒,并将其导入
在这里插入图片描述

创建 Material (Assets 上下文菜单 -> create -> Material) 起名 mysky,并在Inspector中选择Shader -> Skybox -> 6Sided
在这里插入图片描述
在资源贴图中,选择对应位置的贴图,将其放入右侧的空格中
在这里插入图片描述
运行后效果如下
在这里插入图片描述还能通过Terrain构建地形以及添加植物等
在这里插入图片描述

  • 写一个简单的总结,总结游戏对象的使用
    游戏对象是所有其他组件的容器,游戏中的所有对象本质上都是游戏对象。
    游戏对象主要包括:
    实体对象:如3d object的球、方块等
    辅助对象:如camera摄像机、light光线、audio声音等

2、编程实践

牧师与魔鬼 动作分离版

UML类图

在这里插入图片描述

动作基类(SSAction)

  • ScriptableObject 是不需要绑定 GameObject 对象的可编程基类。这些对象受 Unity 引擎场景管理
  • protected 防止用户自己 new 对象
  • 使用 virtual 申明虚方法,通过重写实现多态。这样继承者就明确使用 Start 和 Update 编程游戏对象行为
  • 利用接口(ISSACtionCallback)实现消息通知,避免与动作管理者直接依赖
public class SSAction : ScriptableObject
{
    public bool enable = true;
    public bool destroy = false;

    public GameObject gameObject;
    public Transform transform;
    public SSActionCallback CallBack;

    public virtual void Start()
    {
        throw new System.NotImplementedException();
    }

    public virtual void Update()
    {
        throw new System.NotImplementedException();
    }
}

简单动作实现(CCMoveToAction)

  • 实现具体动作,将一个物体移动到目标位置,并通知任务完成
public class CCMoveToAction : SSAction
{
    public Vector3 target;
    public float speed;

    private CCMoveToAction() { }
    public static CCMoveToAction getAction(Vector3 target, float speed)
    {
        CCMoveToAction action = ScriptableObject.CreateInstance<CCMoveToAction>();
        action.target = target;
        action.speed = speed;
        return action;
    }

    public override void Update()
    {
        this.transform.position = Vector3.MoveTowards(transform.position, target, speed * Time.deltaTime);
        if (transform.position == target)
        {
            destroy = true;
            CallBack.SSActionCallback(this);
        }
    }

    public override void Start()
    {

    }
}

顺序动作组合类实现(CCSequenceAction)

  • 实现一个动作组合序列,顺序播放动作:
public class CCSequenceAction : SSAction, SSActionCallback
{
    public List<SSAction> sequence;
    public int repeat = 1; 
    public int currentActionIndex = 0;

    public static CCSequenceAction getAction(int repeat, int currentActionIndex, List<SSAction> sequence)
    {
        CCSequenceAction action = ScriptableObject.CreateInstance<CCSequenceAction>();
        action.sequence = sequence;
        action.repeat = repeat;
        action.currentActionIndex = currentActionIndex;
        return action;
    }

    public override void Update()
    {
        if (sequence.Count == 0) return;
        if (currentActionIndex < sequence.Count)
        {
            sequence[currentActionIndex].Update();
        }
    }

    public void SSActionCallback(SSAction source)
    {
        source.destroy = false;
        this.currentActionIndex++;
        if (this.currentActionIndex >= sequence.Count)
        {
            this.currentActionIndex = 0;
            if (repeat > 0) repeat--;
            if (repeat == 0)
            {
                this.destroy = true;
                this.CallBack.SSActionCallback(this);
            }
        }
    }

    public override void Start()
    {
        foreach (SSAction action in sequence)
        {
            action.gameObject = this.gameObject;
            action.transform = this.transform;
            action.CallBack = this;
            action.Start();
        }
    }

    void OnDestroy()
    {
        foreach (SSAction action in sequence)
        {
            DestroyObject(action);
        }
    }
}

动作管理基类(SSActionManager)

  • 这是动作对象管理器的基类,实现了所有动作的基本管理:
public class SSActionManager : MonoBehaviour
{
    private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();
    private List<SSAction> waitingToAdd = new List<SSAction>();
    private List<int> watingToDelete = new List<int>();

    protected void Update()
    {
        foreach (SSAction ac in waitingToAdd)
        {
            actions[ac.GetInstanceID()] = ac;
        }
        waitingToAdd.Clear();

        foreach (KeyValuePair<int, SSAction> kv in actions)
        {
            SSAction ac = kv.Value;
            if (ac.destroy)
            {
                watingToDelete.Add(ac.GetInstanceID());
            }
            else if (ac.enable)
            {
                ac.Update();
            }
        }

        foreach (int key in watingToDelete)
        {
            SSAction ac = actions[key];
            actions.Remove(key);
            DestroyObject(ac);
        }
        watingToDelete.Clear();
    }
    
    public void addAction(GameObject gameObject, SSAction action, SSActionCallback ICallBack)
    {
        action.gameObject = gameObject;
        action.transform = gameObject.transform;
        action.CallBack = ICallBack;
        waitingToAdd.Add(action);
        action.Start();
    }
}

动作管理器(FirstSceneActionManager)

  • 管理船和游戏角色的移动,这个类体现了动作分离的思想
public class FirstSceneActionManager : SSActionManager, SSActionCallback
{
    public SSActionEventType Complete = SSActionEventType.Completed;

    public void BoatMove(BoatController Boat)
    {
        Complete = SSActionEventType.Started;
        CCMoveToAction action = CCMoveToAction.getAction(Boat.GetDestination(), Boat.GetMoveSpeed());
        addAction(Boat.GetGameObject(), action, this);
        Boat.ChangeState();
    }

    public void GameObjectsMove(GameObjects GameObject, Vector3 Destination)
    {
        Complete = SSActionEventType.Started;
        Vector3 CurrentPos = GameObject.GetPosition();
        Vector3 MiddlePos = CurrentPos;
        if (Destination.y > CurrentPos.y)
        {
            MiddlePos.y = Destination.y;
        }
        else
        {
            MiddlePos.x = Destination.x;
        }
        SSAction action1 = CCMoveToAction.getAction(MiddlePos, GameObject.GetMoveSpeed());
        SSAction action2 = CCMoveToAction.getAction(Destination, GameObject.GetMoveSpeed());
        SSAction seqAction = CCSequenceAction.getAction(1, 0, new List<SSAction> { action1, action2 });
        this.addAction(GameObject.GetGameobject(), seqAction, this);
    }

    public void SSActionCallback(SSAction source)
    {
        Complete = SSActionEventType.Completed;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值