博主的AR游戏是使用Vuforia做的,Vuforia组件在你安装Unity时应该是可选的,如果忘记选了,那就去Vuforia的网站上下载就可以了。
选第二个安装就可以了。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Btn_Cube : MonoBehaviour
{
public GameObject btn;//定义物体变量 btn
public GameObject cube;//定义物体变量 cube
// Start is called before the first frame update
void Start()
{
Button btn_cube = btn.GetComponent<Button>();//获取Button组件
btn_cube.onClick.AddListener(btnClick);//点击事件
}
void btnClick(){
cube.SetActive(false); //隐藏物体cube
}
// Update is called once per frame
void Update()
{
}
}
博主只是提一下自己在开发的时候遇到的感觉有用的知识,具体用法需要读者自行百度搜索。下面我以挂载在方块Cube下的脚本Btn_Cube为例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Btn_Cube : MonoBehaviour
{
public GameObject btn;
public GameObject cube;
// Start is called before the first frame update
void Start()
{
// API:GameObject.GetComponent<脚本>()。常用于获取UI组件信息并进行操作,Componet就是右侧栏里面所有的脚本
Button btn_cube = btn.GetComponent<Button>();
// API:Button.onClick.AddListener(点击事件)。按钮点击事件
btn_cube.onClick.AddListener(btnClick);
// Transform和GameObject是Unity中比较重要的两个变量类型,两者可以相互转换
Transform t = cube.transform;
GameObject obj = t.gameObject;
// API:Transform.Find("")即寻找该物体下的子物体,这时可以不用拖拽物体到GameObject变量上,还有其他常用的其他方法,自行百度
Transform t_child = t.Find("");
// API:GameObject.SetActive()控制物体显示隐藏的方法
obj.SetActive(false);
// API:GameObject.activeInHierarchy判断物体是否隐藏的方法
if(obj.activeInHierarchy){
}
// API:触摸点击事件,射线法,具体自行百度
if(Input.GetMouseButtonDown(0)){
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
// touchCount:手指数量。
// Input.GetTouch(0).phase:触碰状态。
// TouchPhase.Began:刚触碰时
if(Input.touchCount == 1 && Input.GetTouch(0).phase == TouchPhase.Began){
// 射线碰撞到的碰撞体所在的物体
GameObject hitobj = hit.collider.gameObject;
}
}
}
}
void btnClick(){
cube.SetActive(false);
}
// Update is called once per frame
void Update()
{
}
}
用Unity实现一个简单的拼图游戏,博主也是学习了别人的博客,在这里分享一下:https://gameinstitute.qq.com/community/detail/124936。
新建三个脚本,分别为GameManager、ImageCreater、DragOnPic,ImageCreater挂在Raw Image上,DragOnPic挂载Cell中的Image上
using UnityEngine;
public class GameManager
{
static public void RandomArray(Sprite[] sprites)
{
for (int i = 0; i < sprites.Length; i++)
{
//随机抽取数字中的一个位置,并将这张图片与第i张图片交换.
int index = Random.Range(i, sprites.Length);
Sprite temp = sprites[i];
sprites[i] = sprites[index];
sprites[index] = temp;
}
}
///
/// Sets the parent.
///
static public void SetParent(Transform mine, Transform target, Transform oldParent)
{
//如果检测到图片,则交换父物体并重置位置.
switch (target.tag)
{
case "Cell":
mine.SetParent(target.parent);
target.SetParent(oldParent);
mine.localPosition = Vector3.zero;
target.localPosition = Vector3.zero;
break;
default:
mine.SetParent(oldParent);
mine.localPosition = Vector3.zero;
break;
}
}
///
/// Checks is win.
///
static public bool CheckWin()
{
for (int i = 0; i < ImageCreater._instance.transform.childCount; i++)
{
if (ImageCreater._instance.transform.GetChild(i).name != ImageCreater._instance.transform.GetChild(i).transform.GetChild(0).name)
{
return false;
}
}
return true;
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ImageCreater : MonoBehaviour
{
public static ImageCreater _instance;
//存储裁剪好图片的数组.
public Sprite[] sprites;
//格子的预设体.
public GameObject cellPrefab;
// Start is called before the first frame update
void Start()
{
_instance = this;
CreateImages();
}
private void CreateImages()
{
//将图片数组随机排列.
GameManager.RandomArray(sprites);
//生产图片.
for (int i = 0; i < sprites.Length; i++)
{
//通过预设体生成图片.
GameObject cell = (GameObject)Instantiate(cellPrefab);
//设置cell的名字方便检测是否完成拼图.
cell.name = i.ToString();
//获取cell的子物体.
Transform image = cell.transform.GetChild(0);
//设置显示的图片.
image.GetComponent<Image>().sprite = sprites[i];
//设置子物体的名称,方便检测是否完成拼图.
int tempIndex = sprites[i].name.LastIndexOf('_');
image.name = sprites[i].name.Substring(tempIndex + 1);
//将Cell设置为Panel的子物体.
cell.transform.SetParent(this.transform);
//初始化大小.
cell.transform.localScale = Vector3.one;
}
}
// Update is called once per frame
void Update()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class DragOnPic : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
//记录下自己的父物体.
Transform myParent;
//Panel,使拖拽是显示在最上方.
Transform tempParent;
CanvasGroup cg;
RectTransform rt;
//记录鼠标位置.
Vector3 newPosition;
void Awake()
{
//添加CanvasGroup组件用于在拖拽是忽略自己,从而检测到被交换的图片.
cg = this.gameObject.AddComponent<CanvasGroup>();
rt = this.GetComponent<RectTransform>();
tempParent = GameObject.Find("Canvas").transform;
}
public void OnBeginDrag(PointerEventData eventData)
{
//拖拽开始时记下自己的父物体.
myParent = transform.parent;
//拖拽开始时禁用检测.
cg.blocksRaycasts = false;
this.transform.SetParent(tempParent);
}
void IDragHandler.OnDrag(PointerEventData eventData)
{
//推拽是图片跟随鼠标移动.
RectTransformUtility.ScreenPointToWorldPointInRectangle(rt, Input.mousePosition, eventData.enterEventCamera, out newPosition);
transform.position = newPosition;
}
public void OnEndDrag(PointerEventData eventData)
{
//获取鼠标下面的物体.
GameObject target = eventData.pointerEnter;
//如果能检测到物体.
if (target)
{
GameManager.SetParent(this.transform, target.transform, myParent);
}
else
{
this.transform.SetParent(myParent);
this.transform.localPosition = Vector3.zero;
}
//拖拽结束时启用检测.
cg.blocksRaycasts = true;
//检测是否完成拼图.
if (GameManager.CheckWin())
{
Debug.Log("Win!!!");
}
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
Copying assembly from ‘Temp/Unity.TextMeshPro.dll’ to 'Library/ScriptAssembl
翻译过来就是某东西无法复制,百度了一下最终解决了,博主是因为电脑管家的拦截才报这个错误的,把电脑管家关了之后重启一下项目就可以了。
用自己习惯的工具来写代码更加方便一点,而且装好插件的话会有代码提示,大大提高了写代码的效率,十分推荐大家使用。
博主自己是使用VScode,还需要装两个插件,分别是C#和Debugger for Unity。
理论上讲,这两个插件就可以实现代码补全功能,但实际上博主还是无法实现vscode对Unity的代码补全功能,最后捣鼓了一下,成功解决了问题。
当时VScode控制台会有错误提示(没有把图截下来),其实按照控制台的提示去把需要的东西下载下来就可以了。
博主遇到的情况是这样的:
随便点开项目文件夹画红线的三个文件之一,可以看到
但是控制台提示我并没有找到这个版本,那么就把对应版本的下载下来就可以了。
4.7.1版本的下载地址是:https://dotnet.microsoft.com/download/dotnet-framework/net471。安装完之后重启VScode就可以了。
void Start()
{
GameObject obj;
Transform t = obj.transform.Find("");
Image image = t.GetComponent<Image>();
//Resources.Load表示路径位于Resources,即后面填写的路径path要在文件夹Resources里面的
//输出获取到的图片资源的名字
Debug.Log("1:" + image.sprite.name);
image.overrideSprite = Resources.Load("path",typeof(Sprite))as Sprite;
Debug.Log("2" + image.sprite.name);
Sprite s = Resources.Load<Sprite>("");
image.sprite = s;
}
overrideSprite是临时的修改图片,意思是不会真正将图片更换,而是覆盖另一张图片在其上。对比两次输出即可发现图片资源没有被更换
void Start()
{
GameObject obj;
Transform t = obj.transform.Find("");
Image image = t.GetComponent<Image>();
//输出获取到的图片资源的名字
Debug.Log("1:" + image.sprite.name);
Sprite s = Resources.Load<Sprite>("path");
image.sprite = s;
Debug.Log("2" + image.sprite.name);
}
这一种方式则是会真正替换掉原来的图片,假如你需要对图片替换前后进行判断的话,就需要选择这种方式来替换图片。