2016-06-09 01:30:08 ocanio 阅读数 5432

扯淡:平时玩一些3d沙盒游戏,如果你“尾随”街上的路人或者车子,可以发现,他们都是按照指定路径点循环移动的,如果你也有试过,那说明你也挺无聊的233


思路

让物体朝向目标点,然后向前移动,到达一个目标点后,朝向下一个目标点……


代码

using UnityEngine;
using System.Collections;

public class Move : MonoBehaviour {
    public float speed = 2; //[1] 物体移动速度
    public Transform []target;  // [2] 目标
    public float delta = 0.2f; // 误差值
    private static int i = 0;

    void Update () {
        moveTo ();  
    }

    void moveTo(){
        // [3] 重新初始化目标点
        target [i].position = new Vector3 (target [i].position.x, transform.position.y, target [i].position.z);

        // [4] 让物体朝向目标点 
        transform.LookAt (target [i]);

        // [5] 物体向前移动
        transform.Translate (Vector3.forward * Time.deltaTime * speed);

        // [6] 判断物体是否到达目标点
        if (transform.position.x > target[i].position.x - delta 
            && transform.position.x < target[i].position.x + delta
            && transform.position.z > target[i].position.z - delta
            && transform.position.z < target[i].position.z + delta)
            i = (i+1)%target.Length;
    }
}

补充注释

>> [2] public Transform []target;

在场景中创建 Empty GameObject ,
将其放到你想要的位置上,
那么这个位置即为目标点,
然后把这个 Empty GameObjecttransform 作为脚本的输入,
通过 target[i].transform.position 来得到我们需要的目标点。

//用这种方法可以比较方便的设置你需要的路径点 ,
//因为你只需要创建多个 Empty GameObject,
//放到指定位置,然后拖到脚本的输入即可。

>> [3] target [i].position = new Vector3

(target [i].position.x, transform.position.y, target [i].position.z);

其实这里的初始化,
主要是把目标的y坐标和物体的y坐标对齐,
这样可以省去放置目标点时的麻烦,
当然如果你的物体需要爬上爬下就省略此步骤

>>[6] if (transform.position.x > target[i].position.x - 0.2f

&& transform.position.x < target[i].position.x + 0.2f

&& transform.position.z > target[i].position.z - 0.2f

transform.position.z < target[i].position.x + 0.2f)

i = (i+1)%target.Length;

可能有些人会说,
你zhi4 zhang4 吗,
为什么不直接if(transform.position == target[i].position) 呢,
兄台你有所不知,
如果你实际运行的话,
你会发现物体“到达”目标点后,
就一直在原地抽搐,
不会走向下一个目标点了,
因为我们的点都是浮点数,
浮点数0.3并不等于数学上的0.3,
浮点数0.3可能为0.299999999也可能为0.30000000001(举个栗子,大概就这意思)
所以我们的物体看似到达了目标点,
其实一直在无限接近,
所以这时候就需要设置一个误差值,
让物体到达目标点的周围一定范围后,
来确定到达了目标点。
至于i = (i+1)%target.Length;
可以让我们的物体循环运动。


具体操作

这里写图片描述

//为方便观察,我把目标均弄成白色球体,移动物体设置成红色球体
1.创建6个白色球体和一个红色球体
2.设置好他们各自的位置
3.给红色球体脚本(Move.cs)
4.设置Target 的 Size大小(你想让物体移动到多少个点就设为多少)
5.然后把6个白色球体分别拖到Element0~Element5
6.点击运行,即可观察到小球沿指定路径循环运动。


相关资料

游戏蛮牛Unity用户手册

2017-05-17 17:24:11 yongh701 阅读数 6418

毕竟游戏里面,不能所有物体都要求它按照一条定向的路径移动的,需要给玩家一个操作空间,让玩家点哪,这东西自然而然地去哪里。因此自《【iTween】指定路径位移》(点击打开链接)之后,自动寻路的需求应运而生。不过,Unity3D自带的功能,就能完成这个看起来高大上的功能。下面举一个例子说明这个问题。

如下图,摆了4个cube当作墙,然后摆一个球,当作游戏的主角,鼠标点哪走哪,但关键是不会出现穿墙的情况。


具体做法如下:

一、场景布置

1、如下图所示,没什么好说的。


2、之后先将这个场景保存为Navmesh,然后如下图打开自动寻路设置界面。


如下图所示,在Navigation界面,对所有代表墙的Cube和地板Plane都勾上Navigation Static。表示这些都是寻路的阻碍物。

都设置好再点击Bake。烘培之后就会出现如下图的淡蓝色的,可移动的区域。这是Unity3D自己能计算出来的。


3、给球加上Nav Mesh Agent这个组件,表示它是一个被导航体。里面的半径、速度等,Unity3D给你上这个组件的时候,基本会给你计算好的,如果你是自己导入的3D模型估计需要将半径改到和你的3D模型基本匹配的程度。


4、之后再给Plane上一个plane标签,用于碰撞检测。因为Unity3D中,鼠标点击Plane,需要是在鼠标点击的屏幕像素点,发出一条直线和Unity3D世界中物体碰撞,才能找到准确的点击的。这在《【Unity3D】判断是否鼠标点击物体与血条制作》(点击打开链接)已经说了,这里不再赘述了。毕竟这个plane注定要会被我们一会儿疯狂点击的。


二、脚本设置

给球sphere赋予如下的Navigation.cs:

using UnityEngine;
using System.Collections;

public class Navigation : MonoBehaviour
{
    private NavMeshAgent navMeshAgent;
    void Start()
    {
        navMeshAgent = gameObject.GetComponent<NavMeshAgent>();//初始化navMeshAgent
    }
    void Update()
    {
        if (Input.GetMouseButtonDown(0))//鼠标左键点下  
        {
            Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition);//住摄像机向鼠标位置发射射线 
            RaycastHit mHit;
            if (Physics.Raycast(mRay, out mHit))//射线检验 
            {
                if (mHit.collider.gameObject.tag == "plane")
                {
                    navMeshAgent.SetDestination(mHit.point);//mHit.point就是射线和plane的相交点,实为碰撞点
                }
            }
        }
    }
}
则能够享受NavMeshAgent带来的Unity3D自动寻路的欢乐~(*^_^*)

2013-07-26 17:30:43 wyz365889 阅读数 6695

基本功能实现:物体通过鼠标左键上下移动,中间键缩放、右键旋转,30秒没操作,物体自动旋转


实例代码:

using UnityEngine;
using System.Collections;


public class Script_07_11 : MonoBehaviour 
{

	public Transform target;
	
	private int MouseWheelSensitivity = 50;
	private int MouseZoomMin = 20;
	private int MouseZoomMax = 112;
	private float normalDistance = 500;
	
	private bool flag_Roable = true;	//自动旋转标志
	
	private Vector3 normalized;
	

	private float xSpeed = 250.0f;
	private float ySpeed = 120.0f;


	private float x = 0.0f;
	private float y = 0.0f;
	

	private System.DateTime  oldTime;
	private System.DateTime  nowTime;

	void Start () 
	{
		
		oldTime = System.DateTime.Now;
		//transform.LookAt(target);
		
		
	}
	
	void Update ()
	{
		nowTime = System.DateTime .Now;
		System.TimeSpan	 ts1 = new System.TimeSpan(oldTime.Ticks);
		System.TimeSpan	 ts2 = new System.TimeSpan(nowTime.Ticks);
		
		System.TimeSpan ts =  ts2.Subtract(ts1).Duration();
		
		if(ts.Seconds>30 && !Input.anyKey)
		{
			flag_Roable = true;
			oldTime = System.DateTime.Now;
		}
		
		if(flag_Roable && Input.anyKey)
		{
			flag_Roable = false;
		}
		
		if(flag_Roable)	//自动旋转
		{
			
			x-=Time.deltaTime*30;
			
			
			var rotation = Quaternion.Euler(0,x,0);
			transform.RotateAround(target.position,Vector3.up,0.3f);	
		}
		else
		{
			if(Input.GetMouseButton(1))
			{
				if(Input.GetAxis("Mouse X")<0)   
					transform.RotateAround(target.position,Vector3.down,4); 
				if(Input.GetAxis("Mouse X")>0)
					transform.RotateAround(target.position,Vector3.up,4);
			}
			else if (Input.GetAxis("Mouse ScrollWheel") != 0)
			{
				
			    //normalized = (transform.position - CameraTarget).normalized;
				
				if (normalDistance >= MouseZoomMin && normalDistance <= MouseZoomMax)
				{
					normalDistance -= Input.GetAxis("Mouse ScrollWheel") * MouseWheelSensitivity;
				}
				if (normalDistance < MouseZoomMin)
				{
					normalDistance = MouseZoomMin;
				}
				if (normalDistance > MouseZoomMax)
				{
					normalDistance = MouseZoomMax;
				}
					//transform.position =	   normalized * normalDistance;
				transform.camera.fieldOfView = normalDistance;
				
			}
			else if(Input.GetMouseButton(0))
			{
				//print("wyz-==="+Input.GetAxis("Mouse Y"));
				if(Input.GetAxis("Mouse Y")<0)  //down
				{
					Vector3 temp=Vector3.up * 60.0f * Time.deltaTime;
					
					print("wyz==up==="+transform.localPosition.y);
					if(transform.localPosition.y>300)
					{
						temp=Vector3.up * 5.0f * Time.deltaTime;
						transform.Translate(temp);
					}
					else
					{
						transform.Translate(temp);		
					}
				}
						
				if(Input.GetAxis("Mouse Y")>0)  //up 
				{
					print("wyz==donw==="+transform.localPosition.y);
					Vector3 temp=Vector3.down * 60.0f * Time.deltaTime;
				
					
					if(transform.localPosition.y<-300)
					{
						temp=Vector3.up * 5.0f * Time.deltaTime;
						transform.Translate(temp);
					}
					else
					{
						transform.Translate(temp);				
					}			
				}
			
			}	
			
		}
		
	}
	
	
}


2016-07-11 17:57:41 CSDN_xin_L 阅读数 3659

当鼠标移动到按钮上,按钮做出响应动画。比如手游三国杀中的开始游戏,当手指碰撞到开始游戏时,开始游戏按钮变大的动画制作方法。在翻阅相关官方文档后,发现了一个简易的方法。

鼠标响应动画

对于Button添加组件Animator。
在组件Animator中Navigation中选择Automatic后自动产生动画控制器,之后便可以在Unity3d的动画控制器处选择Highlighted。
这里写图片描述
点击录制按钮然后选择在第0帧处,将按钮的Scale由原本的1,1,1改为1.2,1.2,1.2即可。之后停止录制。
这里写图片描述
这里写图片描述
这样设置完成后当你的鼠标碰撞到按钮后,按钮变会自动放大。

2018-11-16 22:57:06 qq_36171287 阅读数 1302

目录

一、在Hierarchy窗口中创建场景,之后塑造一个平面作为地板,将元件命名为background。再创建一个正方体,命名为player。

二、在project窗口中创建两个folder文件夹。一个命名为材料material,一个命名为脚本scripts。

三、编写playermove移动的代码。

四、设置敌人物体


一、在Hierarchy窗口中创建场景,之后塑造一个平面作为地板,将元件命名为background。再创建一个正方体,命名为player。

二、在project窗口中创建两个folder文件夹。一个命名为材料material,一个命名为脚本scripts。

在material文件夹中创建两个material,调整颜色,创建好之后直接拖动到player和background之上。在scripts文件夹中创建C# 脚本文件,命名为playermove。双击脚本文件,在VS中打开。

三、编写playermove移动的代码。

需要在player原件中添加刚体,否则物体不能受力。

接下来在VS中的脚本代码中进行物体移动的编码。然后把playermove脚本拖动到player元件上。点击运行,按下WASD四建就可以对正方体player进行移动操作了。

public class playermove : MonoBehaviour {
    
    public float moveSpeed; //移速
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
        //获取键盘数值
        //var 自动匹配目标类型
        var move = new Vector3(Input.GetAxisRaw("Horizontal"),0,Input.GetAxisRaw("Vertical")); //构建一个向量,获取X,Y,Z三轴的变量
        var rigidbody = GetComponent<Rigidbody>();
        rigidbody.AddForce(move * moveSpeed);  //给刚体添加一个力

	}
}

 

 如果不想让正方体滚动,可以在刚体rigidbody中的Constraints的选项中把Freeze Rotation中的x,y,z全部锁定。物体的移动就会变成平移。

四、设置敌人物体

与创建player方块相同,创建enemy敌人方块。创建一个patrol脚本,将脚本拖动到enemy元件上。打开patrol,进行物体固定轨道移动的编码。

patrol脚本的代码如下: 

public class patrol : MonoBehaviour {

    public GameObject[] gameObjectArray; //建一个数组 也可以写作public List<GameObject> gameObjectList;
    public int index = 0;   //设置数组索引
    public float moveSpeed; //移速

    // Use this for initialization
    void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {   //Update是每帧来计算的,游戏每一帧会运行update一次
        //设置物体缓慢移动的方法MoveToward(current/当前的位置,target/目标位置,maxDistanceDelta)
        //添加了Time.deltaTime是时间增量,渲染完上一帧的时间
        transform.position = Vector3.MoveTowards(transform.position,gameObjectArray[index].transform.position,moveSpeed * Time.deltaTime); //这是新的移动位置,把新的位置赋值给position
    }
}

回到unity界面,新建三个空坐标

移动三个位置

 点击enemy,将GameObject拖动到Game Object Array中,可以自己设置Move Speed的速度。

现在只是运行了一次数组中enemy的行动,所以对patrol的代码进行修改,结果如下:

public class patrol : MonoBehaviour {

    public GameObject[] gameObjectArray; //建一个数组 也可以写作public List<GameObject> gameObjectList;
    public int index = 0;   //设置数组索引
    public float moveSpeed; //移速

    // Use this for initialization
    void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {   //Update是每帧来计算的,游戏每一帧会运行update一次
        //设置物体缓慢移动的方法MoveToward(current/当前的位置,target/目标位置,maxDistanceDelta)
        //添加了Time.deltaTime是时间增量,渲染完上一帧的时间
        if (index > gameObjectArray.Length-1) //如果索引超出数组下标
        {
            index = 0;
        }
        transform.position = Vector3.MoveTowards(transform.position,gameObjectArray[index].transform.position,moveSpeed * Time.deltaTime); //这是新的移动位置,把新的位置赋值给position
        if (transform.position== gameObjectArray[index].transform.position) //判断,如果地址等于目标地址
        {
            index++;

        }
    }
}

返回unity3d运行,enemy元件就会循环运动。

 

编写成果:https://download.csdn.net/download/qq_36171287/10789964

Unity3D 模型分块

阅读数 1589

没有更多推荐了,返回首页