PlayerMovement

public class PlayerMovement : MonoBehaviour
{public CharacterController controller;public float speed = 12f;public float gravity = -9.81f * 2;public float jumpHeight = 3f;public Transform groundCheck;//落地检测public float groundDistance = 0.4f;//落地检测距离public LayerMask groundMask;//声明打算用于落地检测的层Vector3 velocity;bool isGrounded;// Update is called once per framevoid Update(){//checking if we hit the ground to reset our falling velocity, otherwise we will fall faster the next timeisGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);if (isGrounded && velocity.y < 0){velocity.y = -2f;}float x = Input.GetAxis("Horizontal");float z = Input.GetAxis("Vertical");//right is the red Axis, foward is the blue axisVector3 move = transform.right * x + transform.forward * z;controller.Move(move * speed * Time.deltaTime);//如果在地面上,就可以跳(不许连跳)(以后多加个能力参数来解锁连跳吧)if (Input.GetButtonDown("Jump") && isGrounded){//the equation for jumpingvelocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);}velocity.y += gravity * Time.deltaTime;controller.Move(velocity * Time.deltaTime);}
}

MouseMovement

public class MouseMovement : MonoBehaviour
{public float mouseSensitivity = 100f;float xRotation = 0f;float YRotation = 0f;void Start(){//将鼠标光标固定在屏幕中央(不可视)Cursor.lockState = CursorLockMode.Locked;}void Update(){//如果背包被打开if (InventorySystem.Instance.isOpen == false){float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;//控制以x轴为轴心的旋转(抬头/低头)xRotation -= mouseY;//保证抬头/低头幅度不超过90°xRotation = Mathf.Clamp(xRotation, -90f, 90f);//控制以y轴为轴心的旋转(左右看)YRotation += mouseX;//applying both rotationstransform.localRotation = Quaternion.Euler(xRotation, YRotation, 0f);}}
}

SelectionManager

public class SelectionManager : MonoBehaviour
{//让SelectionManager变成一个单例,为了实现这一目的还创建了awak方法,不懂public static SelectionManager instance { get; set; }public bool onTarget;public GameObject interaction_Info_UI;//声明一个UI交互界面,绑定之前Text interaction_text;//声明组件文本,用于获取UI交互界面的文本组件public Image centerDotImage;public Image handIcon;private void Start(){onTarget = false;interaction_text = interaction_Info_UI.GetComponent<Text>();//获取UI交互界面的文本组件}void Update(){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//从屏幕中心向鼠标位置发射射线(之前把鼠标位置固定在屏幕的正中间)RaycastHit hit;//射线命中信息if (Physics.Raycast(ray, out hit))//如果射线击中了,射线命中信息hit存储相关信息{var selectionTransform = hit.transform;//获取被击中单位的位置InteractableObject ourInteractable = selectionTransform.GetComponent<InteractableObject>();if (ourInteractable&&ourInteractable.playerInRange)//如果被击中单位时可互动对象InteractableObject才继续 2/这里进行过修改,保证角色进入一定范围才显示{onTarget = true;ourInteractable.onTarget = true;interaction_text.text = selectionTransform.GetComponent<InteractableObject>().GetItemName();//修改UI交互界面的文本为可互动对象的名字interaction_Info_UI.SetActive(true);//把先前禁用的UI交互界面打开,以至于我们在屏幕上可以看到文本信息if(ourInteractable.CompareTag("pickable"))//如果对象为可拾取的单位{centerDotImage.gameObject.SetActive(false);//原先准心禁用handIcon.gameObject.SetActive(true);//提示用准心启用}else{centerDotImage.gameObject.SetActive(true);handIcon.gameObject.SetActive(false);}}else{onTarget = false;interaction_Info_UI.SetActive(false);//反之再次禁用UI交互界面centerDotImage.gameObject.SetActive(true);handIcon.gameObject.SetActive(false);}}else{onTarget = false;interaction_Info_UI.SetActive(false);//如果射线没有击中,也禁用UI交互界面centerDotImage.gameObject.SetActive(true);handIcon.gameObject.SetActive(false);}}private void Awake(){if(instance != null&& instance !=this){Destroy(gameObject);}else{instance = this;}}
}

ItemSlot

public class ItemSlot : MonoBehaviour, IDropHandler
{public GameObject Item{get{if (transform.childCount > 0){return transform.GetChild(0).gameObject;}return null;}}public void OnDrop(PointerEventData eventData){Debug.Log("OnDrop");//if there is not item already then set our item.如果选择的新父级没有子元素if (!Item){DragDrop.itemBeingDragged.transform.SetParent(transform);//设置新的父级DragDrop.itemBeingDragged.transform.localPosition = new Vector2(0, 0);//重设相对位置,让对象图片显示在Slot的正中间}}}

DragDrop

public class DragDrop : MonoBehaviour, IBeginDragHandler, IEndDragHandler, IDragHandler
{//[SerializeField] private Canvas canvas;//对上层对象Canvas的引用private RectTransform rectTransform;//矩阵位置,相对于画布的位置private CanvasGroup canvasGroup;//画布组,这个组件用于保证在我们点击当前游戏对象时它可以与它上层的插槽格分离public static GameObject itemBeingDragged;Vector3 startPosition;Transform startParent;//记录初始父级(原来所处的插槽),之后如果拖拽失败了,游戏对象还要回到初始父级private void Awake(){rectTransform = GetComponent<RectTransform>();canvasGroup = GetComponent<CanvasGroup>();//记得在挂载的对象上添加这个组件,不然会报错}//开始拖拽public void OnBeginDrag(PointerEventData eventData){Debug.Log("OnBeginDrag");canvasGroup.alpha = 0.6f;//修改alpha值,实现当我们开始拖拽时物品图标会变得有些透明canvasGroup.blocksRaycasts = false; //So the ray cast will ignore the item itself.之前我们有一个射线来着,检测碰撞来获取物品信息等的,现在让射线碰撞忽视这个对象startPosition = transform.position;startParent = transform.parent;transform.SetParent(transform.root);//开始拖拽时,游戏对象从一开始的作为插槽Slot的子元素变成了库存屏幕InventoryScreen的子元素itemBeingDragged = gameObject;}//正在拖拽public void OnDrag(PointerEventData eventData){//So the item will move with our mouse (at same speed)  and so it will be consistant if the canvas has a different scale (other then 1);rectTransform.anchoredPosition += eventData.delta;//拖动速度与鼠标速度一致  除以画布缩放倍率可以避免一些bug/canvas.scaleFactor,但这导致实例化物品图标时候会有bug,所以先注释掉}//结束拖拽public void OnEndDrag(PointerEventData eventData){itemBeingDragged = null;//如果移动后父级还是原来那个或者超出了移动范围成为了库存屏幕InventoryScreen的子元素,那么该游戏对象的父级还是原来那个if (transform.parent == startParent || transform.parent == transform.root){transform.position = startPosition;transform.SetParent(startParent);}Debug.Log("OnEndDrag");canvasGroup.alpha = 1f;canvasGroup.blocksRaycasts = true;}}

BluePrint

public class BluePrint : MonoBehaviour
{public string itemName;public string req1 = "";public string req2 = "";public string req3 = "";public string req4 = "";public int req1Amount=0;public int req2Amount=0;public int req3Amount=0;public int req4Amount=0;public int numOfRequirements;public BluePrint(string name,int reqNum,string R1,int R1num,string R2,int R2num)//后面可以重载{itemName = name;numOfRequirements = reqNum;req1 = R1;req2 = R2;req1Amount = R1num;req2Amount = R2num;}}

InteractableObject

public class InteractableObject : MonoBehaviour
{// Start is called before the first frame updatepublic bool playerInRange;public string itemName = "?_?";public bool onTarget = false;private void Update(){if(Input.GetKeyDown(KeyCode.E)&&playerInRange&&onTarget){if(InventorySystem.Instance.CheckIfFull()== false){InventorySystem.Instance.AddToInventory(itemName);Destroy(gameObject);}else{Debug.Log("背包满了,捡不起来");}}}public string GetItemName(){return itemName;}//进入检测范围,将playerInRange置为真private void OnTriggerEnter(Collider other){//j仅对标签为玩家的对象做出反应if(other.CompareTag("Player")){playerInRange = true;}}private void OnTriggerExit(Collider other){if (other.CompareTag("Player")){playerInRange = false;}}}

InventorySystem

 public class InventorySystem : MonoBehaviour
{
//令InventorySystem成为一个单例子(在游戏运行中一直存在且仅存在一个),把这个脚本的所有public类型的属性和脚本公开给所有脚本使用public static InventorySystem Instance { get; set; }public GameObject inventoryScreenUI;//背包UIpublic List<GameObject> slotList = new List<GameObject>();//获取所有slotpublic List<String> itemList = new List<string>();//项目列表,获取被添加进背包的游戏对象名称private GameObject itemToAdd;//将要加入背包的游戏对象private GameObject whatSlotToEquip;//将要被游戏对象插入的slotpublic bool isOpen;//背包被打开public bool isFull;//背包已满//引用Canvas中的PickupPopUppublic GameObject pickupAlert;public Text pickupName;//拾取对象的名字所要显示的文本对象public Image pickupImage;//拾取对象的图片所要显示的图片对象private void Awake(){if (Instance != null && Instance != this){Destroy(gameObject);}else{Instance = this;}}void Start(){isOpen = false;isFull = false;PopulateSlotList();//可以直接打出这个方法,用alt+enter自动生成相应的方法}//初始化背包插槽的列表private void PopulateSlotList(){foreach(Transform child in inventoryScreenUI.transform){if(child.CompareTag("Slot")){slotList.Add(child.gameObject);}}}//根据名字添加游戏对象的预制体public void AddToInventory(string itemName){if(isFull == false)//在背包没满的情况下添加,在没有逻辑错误情况下这个if总会通过,可以保留用以检查bug{whatSlotToEquip = FindNextEmptySlot();//找到空插槽//实例化想要添加到背包内的对象(根据名字实例对象,位置,转角)itemToAdd = Instantiate(Resources.Load<GameObject>(itemName), whatSlotToEquip.transform.position, whatSlotToEquip.transform.rotation);itemToAdd.transform.SetParent(whatSlotToEquip.transform);//确定游戏对象的父级itemList.Add(itemName);//把这个名字添加到项目列表中TriggerPickupPopUP(itemName, itemToAdd.GetComponent<Image>().sprite);//上面所实例化的预制件自身就有Image组件,其下有需要的spriteReCalculateList();CraftingSystem.Instance.RefreshNeededItems();}}//找到下一个空的插槽,理论上调用这个方法的时候一定是有空插槽的private GameObject FindNextEmptySlot(){//在插槽列表中搜索一个空的插槽foreach(GameObject slot in slotList){if (slot.transform.childCount == 0)//一个子元素都没就是空插槽return slot;}return new GameObject();//一般不会由这个返回}void Update(){if (Input.GetKeyDown(KeyCode.I) && !isOpen){inventoryScreenUI.SetActive(true);//唤醒库存UICursor.lockState = CursorLockMode.None;//不再锁定鼠标光标isOpen = true;}else if (Input.GetKeyDown(KeyCode.I) && isOpen){inventoryScreenUI.SetActive(false);//再次点击关闭UIif(CraftingSystem.Instance.isOpen == false)//如果制作面版还打开着就不锁定光标{Cursor.lockState = CursorLockMode.Locked;//锁定鼠标光标}isOpen = false;}}//遍历查找背包中的空插槽public bool CheckIfFull(){int count = 0;if (isFull)return true;foreach(GameObject slot in slotList){if(slot.transform.childCount > 0){count++;}}if(count == 21)//21是目前的最大背包容量,可修改{isFull = true;return true;}else{return false;}}//根据nameToRemove与amonutToRemove从背包中移除同名的物品public void RemoveItem(string nameToRemove,int amonutToRemove){Debug.Log("RemoveItem开始执行");int counter = amonutToRemove;if (counter == 0)return;for(var i = slotList.Count-1;i>=0;i--)//i = 20{if(slotList[i].transform.childCount > 0)//如果有子元素{if(slotList[i].transform.GetChild(0).name == nameToRemove + "(Clone)"&& counter != 0)//插槽子元素的第一个元素的名字是想要移除的名字,0代表第一个元素,应当只有一个元素{Destroy(slotList[i].transform.GetChild(0).gameObject);//摧毁游戏对象counter -= 1;//计数器自减1}}}ReCalculateList();CraftingSystem.Instance.RefreshNeededItems();}//更新itemList并去除因为实例化预制体而出现的Clone后缀public void ReCalculateList(){itemList.Clear();foreach(GameObject slot in slotList){if(slot.transform.childCount> 0){string name = slot.transform.GetChild(0).name;//Stone(Clone)string str = "(Clone)";string finalName = name.Replace(str, "");//StoneitemList.Add(finalName);} }}void TriggerPickupPopUP(string itemName,Sprite itemsprite){pickupAlert.SetActive(true);pickupName.text = itemName;pickupImage.sprite = itemsprite;}
}

CraftingSystem

public class CraftingSystem : MonoBehaviour
{//首先把制作系统成为一个单例public static CraftingSystem Instance { get; set; }public GameObject craftingScreenUI;//对应的UI界面public GameObject toolsScreenUI;//对应的UI界面public List<string> inventoryItemList = new List<string>();//Category Buttons 与选择制作类别相关的按钮Button toolsBTN;//Craft Buttons 与制作相关的按钮Button craftAxeBTN;//制作要求文本Text AxeReq1, AxeReq2;public bool isOpen;//All Blueprintpublic BluePrint AxeBLP;private void Awake(){if (Instance != null && Instance != this){Destroy(gameObject);}else{Instance = this;}}//初始化开关状态,按钮,制作要求文本,蓝图 并且建立委托来添加制作的新物品到背包void Start(){isOpen = false;toolsBTN = craftingScreenUI.transform.Find("ToolsButton").GetComponent<Button>();//引用的是工具制作的按钮,名字要与Hierarchy中取的一样,不然找不到toolsBTN.onClick.AddListener(delegate { OpenToolsCategory(); });AxeReq1 = toolsScreenUI.transform.Find("Axe").transform.Find("req1").GetComponent<Text>();AxeReq2 = toolsScreenUI.transform.Find("Axe").transform.Find("req2").GetComponent<Text>();craftAxeBTN = toolsScreenUI.transform.Find("Axe").transform.Find("Button").GetComponent<Button>();//委托AxeBLP = new BluePrint("Axe", 2, "Stone", 3, "Stick", 3);craftAxeBTN.onClick.AddListener(delegate { CraftAnyItem(AxeBLP); });}//开启制作栏的方法void OpenToolsCategory(){craftingScreenUI.SetActive(false);//关闭选择页面toolsScreenUI.SetActive(true);//开启工具制作页面}void CraftAnyItem(BluePrint bluePrintToCraft){Debug.Log(bluePrintToCraft.itemName);Debug.Log(11111111);//添加item到库存系统InventorySystem.Instance.AddToInventory(bluePrintToCraft.itemName);//从库存系统移除制作物品所消耗的材料InventorySystem.Instance.RemoveItem(bluePrintToCraft.req1,bluePrintToCraft.req1Amount);InventorySystem.Instance.RemoveItem(bluePrintToCraft.req2, bluePrintToCraft.req2Amount);StartCoroutine(cacilate());//这个方法解决了在一次制作后原材料没有真正减少的问题//RefreshNeededItems();}// Update is called once per framevoid Update(){//RefreshNeededItems();//从之前库存管理脚本那里复制来的代码if (Input.GetKeyDown(KeyCode.C) && !isOpen){craftingScreenUI.SetActive(true);//唤醒制作面板UICursor.lockState = CursorLockMode.None;//不再锁定鼠标光标isOpen = true;}else if (Input.GetKeyDown(KeyCode.C) && isOpen){craftingScreenUI.SetActive(false);//再次点击关闭UItoolsScreenUI.SetActive(false);//这个也关闭if(InventorySystem.Instance.isOpen == false){ Cursor.lockState = CursorLockMode.Locked;//锁定鼠标光标}isOpen = false;}}public void RefreshNeededItems(){int stone_count = 0;int stick_count = 0;inventoryItemList = InventorySystem.Instance.itemList;foreach(string itemName in inventoryItemList){switch(itemName){case "Stone":stone_count += 1;break;case "Stick":stick_count += 1;break;}}//...Axe...//AxeReq1.text = $"3 Stone [{stone_count}]";AxeReq2.text = $"3 Stick [{stick_count}]";if(stone_count >= 3 && stone_count >= 3){craftAxeBTN.gameObject.SetActive(true);}else{craftAxeBTN.gameObject.SetActive(false);}}public IEnumerator cacilate(){//yield return new WaitForSeconds(1f);yield return 0;//点击制作后不会再有延迟显示材料的消耗InventorySystem.Instance.ReCalculateList();RefreshNeededItems();}
}

AI_Movement

public class AI_Movement : MonoBehaviour
{//没什么意义,图一乐Animator animator;public float moveSpeed = 0.2f;Vector3 stopPosition;float walkTime;private float walkCounter;//原版用了public,实际在后面的start方法中还是会重置为随机,外界输入的没用float waitTime;private float waitCounter;int WalkDirection;public bool isWalking;// Start is called before the first frame updatevoid Start(){animator = GetComponent<Animator>();//保证预制件不会同时移动/停止walkTime = Random.Range(3, 6);waitTime = Random.Range(1, 7);//移动/停止计时器初始化waitCounter = waitTime;walkCounter = walkTime;//随机选择初始移动方向ChooseDirection();}// Update is called once per framevoid Update(){if (isWalking){//向动画管理器组件传参,保证动画的工作animator.SetBool("isRunning", true);walkCounter -= Time.deltaTime;//根据随机选择的方向移动switch (WalkDirection){case 0:transform.localRotation = Quaternion.Euler(0f, 0f, 0f);transform.position += transform.forward * moveSpeed * Time.deltaTime;break;case 1:transform.localRotation = Quaternion.Euler(0f, 90, 0f);transform.position += transform.forward * moveSpeed * Time.deltaTime;break;case 2:transform.localRotation = Quaternion.Euler(0f, -90, 0f);transform.position += transform.forward * moveSpeed * Time.deltaTime;break;case 3:transform.localRotation = Quaternion.Euler(0f, 180, 0f);transform.position += transform.forward * moveSpeed * Time.deltaTime;break;}if (walkCounter <= 0){stopPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z);isWalking = false;//stop movementtransform.position = stopPosition;animator.SetBool("isRunning", false);//reset the waitCounterwaitCounter = waitTime;}}else{waitCounter -= Time.deltaTime;if (waitCounter <= 0){ChooseDirection();}}}//随机选择一个方向public void ChooseDirection(){WalkDirection = Random.Range(0, 4);isWalking = true;walkCounter = walkTime;}
}

脚本(3D Survival Game Learning)相关推荐

  1. [CVPR2022]3D Photo Stylization: Learning to Generate Stylized Novel Views from a Single Image

    标题:3D Photo Stylization: Learning to Generate Stylized Novel Views from a Single Image 链接:https://ar ...

  2. python生成随机骨料模型代码_Abaqus Python脚本-3D随机球形骨料的生成

    hello,大家晚上好,今天是2020/11/30,周一晚上11点30.脚本时间 又是一个安静的晚上,一个人躲在房间里....写专栏.在脚本文集里,上次分享了一个关于脚本的工具,上上次分享了一个2D的 ...

  3. Unity实用小工具或脚本—3D炫酷UI篇(一)

    一.前言 最近做AR和VR的项目,经常需要用到3D的UI,特意将最近自己捣鼓的这个UI的东西写下来.效果如图所示:主要的动画和素材也是借鉴了 第三方的插件"HoloUIExample&quo ...

  4. 3D Instance Embedding Learning With a Structure-Aware Loss Function for Point Cloud Segmentation

    Abstract 这封信提出了一个在点云上进行3D实例分割的框架.使用3D卷积神经网络作为主干,同时生成语义预测和实例嵌入.除了嵌入信息,点云还提供反映点之间关系的3D几何信息.考虑到这两种类型的信息 ...

  5. unity3d物体移动脚本_Flash脚本-3D透视移动效果

    unity3d物体移动脚本 Many Flashers asked me how to create a 3d perspective effect, so here it is! Download ...

  6. Unity实用小工具或脚本——3D物体带坐标轴的拖拽

    一.前言 我们最近要做一个线路的规划编辑,并且是在三维场景中,编辑完就立马能用.立马能用还好说,有特别多的轮子可以用,在三维场景中实时编辑就有点意思了.其实功能就是类似于在Unity的编辑界面操作一个 ...

  7. 【点云系列】综述: Deep Learning for 3D Point Clouds: A Survey

    文章目录 起因 题目 摘要 1 简介 2 背景 2.1 数据集 2.2 衡量指标 3 3D形状分类 3.1基于多视角的方法 3.2基于体素的方法 3.3 基于点的方法 3.3.1逐点MLP网络 3.3 ...

  8. 三维点云语义分割【综述】 ——Deep Learning for 3D Point Clouds: A Survey

    3D POINT CLOUD SEGMENTATION 3D Semantic Segmentation Projection-based Networks Point-based Networks ...

  9. (NeurIPS 2019) Learning Object Bounding Boxes for 3D Instance Segmentation on Point Clouds

    Abstract 我们提出了一种新颖的.概念上简单的通用框架,用于在3D点云上进行实例分割.我们的方法称为3D-BoNet,遵循每点多层感知器(MLP)的简单设计理念.该框架直接回归点云中所有实例的3 ...

最新文章

  1. Maya与Substance Painter风格化材质阴影和照明学习教程
  2. windows10环境运用SSH和SwitchySharp自由翱翔
  3. linux内核启动配置,启动linux内核配置
  4. linux6.5安装oracle,linux [CentOS 6.5]下安装oracle
  5. Qt文档阅读笔记-重现GUI事件进行单元测试
  6. 如何:在网页中嵌入Silverlight视频
  7. 海外并购频频被阻 中国芯发展之路困难重重
  8. python在工程造价的作用_工程预算的意义何在
  9. python读取dat文件代码-基于python批量处理dat文件及科学计算方法详解
  10. CAD.net二次开发之图层,文字样式,标注样式,标注封装,引线的封装
  11. 转:罗永浩写给俞敏洪的求职信
  12. linux vi命令不能用,linux vi命令的使用方法
  13. Qt 之 QCustomPlot(图形库)
  14. 彻底卸载Tomcat
  15. 【前沿技术RPA】 一文了解 UiPath 状态机 State Machine
  16. uni-app使用Hbuilder X如何安卓APP打包、发布、运行
  17. 行存储和列存储小介绍
  18. 北京格林深瞳算法实习生面试
  19. CSS让背景图适应整个屏幕(填满)
  20. 史上最全的Git使用手册

热门文章

  1. 定位的概念(HTML)
  2. Halcon Opencv 数据的不同
  3. 猴博士、高数叔资源分享
  4. 关于TB67S109AFNAG的应用分享及应用
  5. android.os.TransactionTooLargeException
  6. 双指缩放canvas图片_小程序实现图片双指缩放
  7. 7-8 超速判断(10分)
  8. 排查mysql innodb Lock wait timeout exceeded; try restarting transaction的问题
  9. 导航学说解密 飞蛾扑火现象
  10. 软件测试-黑盒测试2