日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

ch06-物理系统与碰撞——Arrowshooting射箭小游戏

發布時間:2023/12/20 windows 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ch06-物理系统与碰撞——Arrowshooting射箭小游戏 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


游戲內容要求:

1.靶對象為 5 環,按環計分;
2.箭對象,射中后要插在靶上

  • 增強要求:射中后,箭對象產生顫抖效果,到下一次射擊 或 1秒以后

3.游戲僅一輪,無限 trials;

  • 增強要求:添加一個風向和強度標志,提高難度

游戲設計:

預制件構建



    • T1
    • T2:和T1一樣,只是scale的x和z改成2
    • T3:和T1一樣,只是scale的x和z改成1.5
    • T4:和T1一樣,只是scale的x和z改成1
    • T5:和T1一樣,只是scale的x和z改成0.5

值得一提的是,材質交替使用深色和淺色木紋更好看!

    • 父對象

    • Body

    • Head:由于技術不夠好,只能顯式的使用了一個cube,不過好在足夠小,不影響美觀

  • 地面:普通的plane加上材質

腳本掛載


代碼

  • SSDirector:導演類,前面幾次作業用過很多次
using System.Collections; using System.Collections.Generic; using UnityEngine;public class SSDirector : System.Object {private static SSDirector _instance;public ISceneController CurrentScenceController { get; set; }public static SSDirector GetInstance(){if (_instance == null){_instance = new SSDirector();}return _instance;} }
  • ArrowFactory :收發箭,跟飛碟游戲里的差不多
using System.Collections; using System.Collections.Generic; using UnityEngine;public class ArrowFactory : MonoBehaviour {private GameObject arrow = null;private GameObject AB = null;private List<GameObject> usingArrowList = new List<GameObject>();private Queue<GameObject> unusedArrowList = new Queue<GameObject>();public Controllor sceneControler;public void initiate(GameObject AB_){AB = AB_;}public GameObject GetArrow(){//還原工廠AB.transform.SetPositionAndRotation(new Vector3(0, 0, 0), Quaternion.Euler(0, 90, 0));AB.transform.localScale = new Vector3(1, 1, 1);if (unusedArrowList.Count == 0){arrow = Instantiate(Resources.Load<GameObject>("Prefabs/Arrow"));}else{arrow = unusedArrowList.Dequeue();arrow.gameObject.SetActive(true);}arrow.transform.parent = AB.transform;//將弓箭作為AB的子物體arrow.transform.position = new Vector3(0, 0, 0);arrow.transform.rotation = Quaternion.Euler(0, 0, 0);usingArrowList.Add(arrow);return arrow;}public void FreeArrow(){for (int i = 0; i < usingArrowList.Count; i++){if (usingArrowList[i].transform.position.y <= -7 || usingArrowList[i].transform.position.y >= 7){usingArrowList[i].GetComponent<Rigidbody>().isKinematic = true;usingArrowList[i].SetActive(false);usingArrowList[i].transform.position = new Vector3(0, 0, 0);unusedArrowList.Enqueue(usingArrowList[i]);usingArrowList.Remove(usingArrowList[i]);i--;}}} }
  • Controllor :這里借鑒了師兄的風控代碼,重點是弓箭的繞軸旋轉、運動和碰撞
    • MoveBow函數讓弓箭繞交點隨著鼠標的位置反方向擾動,這也是符合我們實際操作弓箭的動作
    • Shoot函數為Arrow添加力,在物理引擎的帶動下弓箭仿真運動
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.SceneManagement;public class Controllor : MonoBehaviour, IUserAction, ISceneController {public scoreRecorder recorder;public ArrowFactory arrow_factory;public ArrowFlyActionManager action_manager;public UserGUI user_gui;private GameObject AB;private GameObject arrow;private GameObject target;private bool game_start = false;private string wind = "";private float wind_directX;private float wind_directY;public int GetScore() { return recorder.score; }public string GetWind() { return wind; }public void Restart() { SceneManager.LoadScene(0); }public void BeginGame() { game_start = true; }void Update() { if (game_start) arrow_factory.FreeArrow(); }public void LoadResources() {target = Instantiate(Resources.Load("Prefabs/target", typeof(GameObject))) as GameObject;AB = Instantiate(Resources.Load("Prefabs/AB", typeof(GameObject))) as GameObject;}public bool haveArrowOnPort() { return (arrow != null); }void Start(){SSDirector director = SSDirector.GetInstance();director.CurrentScenceController = this;LoadResources();arrow_factory = singleton<ArrowFactory>.Instance;arrow_factory.initiate(AB);recorder = gameObject.AddComponent<scoreRecorder>() as scoreRecorder;user_gui = gameObject.AddComponent<UserGUI>() as UserGUI;action_manager = gameObject.AddComponent<ArrowFlyActionManager>() as ArrowFlyActionManager;}public void create(){if (arrow == null){wind_directX = Random.Range(-0.4f, 0.4f);wind_directY = Random.Range(-0.4f, 0.4f);CreateWind();arrow = arrow_factory.GetArrow();}}public void MoveBow(Vector3 fwd,float Xinput,float Yinput){if (!game_start) { return; }Vector3 vaxis = Vector3.Cross(fwd, Vector3.right);AB.transform.Rotate(vaxis, -Xinput * 5, Space.World);Vector3 haxis = Vector3.Cross(fwd, Vector3.up);AB.transform.Rotate(haxis, -Yinput * 5, Space.World);}public void Shoot(float holdTime){if (game_start){Vector3 wind = new Vector3(wind_directX, wind_directY, 0);action_manager.ArrowFly(arrow, wind, holdTime);arrow = null;}}public void CreateWind(){string Horizontal = "", Vertical = "", level = "";if (wind_directX > 0){Horizontal = "西";}else if (wind_directX <= 0){Horizontal = "東";}if (wind_directY > 0){Vertical = "南";}else if (wind_directY <= 0){Vertical = "北";}if ((wind_directX + wind_directY) / 0.2f > -0.1f && (wind_directX + wind_directY) / 0.2f < 0.1f){level = "1 級";}else if ((wind_directX + wind_directY) / 0.2f > -0.2f && (wind_directX + wind_directY) / 0.2f < 0.2f){level = "2 級";}else if ((wind_directX + wind_directY) / 0.2f > -0.3f && (wind_directX + wind_directY) / 0.2f < 0.3f){level = "3 級";}else if ((wind_directX + wind_directY) / 0.2f > -0.5f && (wind_directX + wind_directY) / 0.2f < 0.5f){level = "4 級";}wind = Horizontal + Vertical + "風" + " " + level;}}
  • ArrowCollider :這里主要是借鑒了師兄的代碼,學會了能夠使箭射中靶后停留在靶上的方法,我自己確實沒想出來
using System.Collections; using System.Collections.Generic; using UnityEngine;public class ArrowCollider : MonoBehaviour {public Controllor scene_controller;public scoreRecorder recorder;void Start(){scene_controller = SSDirector.GetInstance().CurrentScenceController as Controllor;recorder = singleton<scoreRecorder>.Instance;}void OnTriggerEnter(Collider c){if (c.gameObject.name == "T1" || c.gameObject.name == "T2" || c.gameObject.name == "T3" || c.gameObject.name == "T4" || c.gameObject.name == "T5"){gameObject.transform.parent.gameObject.GetComponent<Rigidbody>().isKinematic = true;gameObject.SetActive(false);//Debug.Log(this.gameObject.transform.position.x);//Debug.Log(this.gameObject.transform.position.y);float dis = Mathf.Sqrt(this.gameObject.transform.position.x * this.gameObject.transform.position.x + this.gameObject.transform.position.y * this.gameObject.transform.position.y);//Debug.Log("dis"+dis.ToString());float point = 0;if (dis >= 0 && dis < 0.5) point = 4f;else if(dis >= 0.5 && dis < 1) point = 3f;else if(dis >= 1 && dis < 1.5) point = 2f;else if(dis >= 1.5 && dis < 2) point = 1f;else if(dis >= 2 && dis < 2.5) point = 0f;recorder.Record((int)Mathf.Floor(point));}} }
  • UserGUI:負責管理與用戶交互
因為帶中文會亂碼,就不貼出來了
  • action: 管理動作
using System.Collections; using System.Collections.Generic; using UnityEngine;public class SSAction : ScriptableObject {public bool enable = true;public bool destroy = false;public GameObject gameobject;public Transform transform;public ISSActionCallback callback;protected SSAction() { }public virtual void Start() { throw new System.NotImplementedException(); }public virtual void Update() { throw new System.NotImplementedException(); }public virtual void FixedUpdate() { throw new System.NotImplementedException(); } }public enum SSActionEventType : int { Started, Competeted } public interface ISSActionCallback { void SSActionEvent(SSAction source, GameObject arrow = null); } public class SSActionManager : MonoBehaviour, ISSActionCallback {private Dictionary<int, SSAction> actions = new Dictionary<int, SSAction>();private List<SSAction> waitingAdd = new List<SSAction>();private List<int> waitingDelete = new List<int>();protected void Update(){foreach (SSAction ac in waitingAdd) actions[ac.GetInstanceID()] = ac;waitingAdd.Clear();foreach (KeyValuePair<int, SSAction> kv in actions){SSAction ac = kv.Value;if (ac.destroy) waitingDelete.Add(ac.GetInstanceID());else if (ac.enable) ac.Update();}foreach (int key in waitingDelete){SSAction ac = actions[key];actions.Remove(key);DestroyObject(ac);}waitingDelete.Clear();}protected void FixedUpdate(){foreach (SSAction ac in waitingAdd) actions[ac.GetInstanceID()] = ac;waitingAdd.Clear();foreach (KeyValuePair<int, SSAction> kv in actions){SSAction ac = kv.Value;if (ac.destroy) waitingDelete.Add(ac.GetInstanceID());else if (ac.enable) ac.FixedUpdate();}foreach (int key in waitingDelete){SSAction ac = actions[key];actions.Remove(key);DestroyObject(ac);}waitingDelete.Clear();}public void RunAction(GameObject gameobject, SSAction action, ISSActionCallback manager){action.gameobject = gameobject;action.transform = gameobject.transform;action.callback = manager;waitingAdd.Add(action);action.Start();}public void SSActionEvent(SSAction source, GameObject arrow = null){if (arrow != null){ArrowTremble tremble = ArrowTremble.GetSSAction();this.RunAction(arrow, tremble, this);}else{Controllor scene_controller = (Controllor)SSDirector.GetInstance().CurrentScenceController;}} } public class ArrowFlyActionManager : SSActionManager {private ArrowFlyAction fly;public Controllor scene_controller;protected void Start(){scene_controller = (Controllor)SSDirector.GetInstance().CurrentScenceController;scene_controller.action_manager = this;}public void ArrowFly(GameObject arrow, Vector3 wind, float holdTime){fly = ArrowFlyAction.GetSSAction(wind, holdTime);this.RunAction(arrow, fly, this);} } public class ArrowFlyAction : SSAction {private float holdTime;public Vector3 wind;private ArrowFlyAction() { }public static ArrowFlyAction GetSSAction(Vector3 wind, float holdTime_){ArrowFlyAction action = CreateInstance<ArrowFlyAction>();action.holdTime = holdTime_;action.wind = wind;return action;}public override void Update() { }public override void FixedUpdate(){//加上風的力this.gameobject.GetComponent<Rigidbody>().AddForce(wind*10, ForceMode.Force);if (this.transform.position.z >=20 || this.gameobject.tag == "hit"){this.destroy = true;this.callback.SSActionEvent(this, this.gameobject);}}public override void Start(){Transform arrow = this.gameobject.transform;arrow.GetComponent<Rigidbody>().isKinematic = false;Debug.Log(arrow.position);arrow.GetComponent<Rigidbody>().AddForce(-arrow.GetChild(0).position * 40f * holdTime, ForceMode.Impulse);arrow.SetParent(null);//解除父子關系} } public class ArrowTremble : SSAction {float radian = 0;float per_radian = 3f;float radius = 0.01f;Vector3 old_pos;public float left_time = 0.8f;private ArrowTremble() { }public override void Start() { old_pos = transform.position; }public static ArrowTremble GetSSAction(){ArrowTremble action = CreateInstance<ArrowTremble>();return action;}public override void Update(){left_time -= Time.deltaTime;if (left_time <= 0){transform.position = old_pos;this.destroy = true;this.callback.SSActionEvent(this);}radian += per_radian;float dy = Mathf.Cos(radian) * radius;transform.position = old_pos + new Vector3(0, dy, 0);}public override void FixedUpdate() { } }
  • interface:里面含有動作類的接口
  • scoreRecorder:記錄分數,離中心的距離越近分數越高
  • singleton:單實例

使用的免費Asset:

  • Fantasy Skybox FREE:常用天空盒
  • Low Poly RPG Fantasy Weapons Lite:弓箭
  • Military target:靶(這個我沒有用,不過做出來應該不錯)

鏈接:

項目地址: ch06-ArrowShooting

演示視頻: 【Unity3D】ArrowShooting小游戲演示

參考博客-1: Unity3d–打靶游戲

參考博客-2: Unity3d學習之路-簡單打靶游戲

總結

以上是生活随笔為你收集整理的ch06-物理系统与碰撞——Arrowshooting射箭小游戏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。