2013-09-13 09:15:38 u012106046 阅读数 5345
1.转向
(1)根据目标点
rotation = Quaternion.LookRotation(target - transform.position);
  transform.rotation = rotation;
 //transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * rotatespeed);平滑
(2)根据速度
 Vector3 v = rigidbody.velocity;
 transform.localRotation = Quaternion.AngleAxis(Mathf.Rad2Deg * Mathf.Atan2(v.x, v.z), Vector3.up);
2.朝目标点移动
transform.position = Vector3.MoveTowards(transform.position, target, Time.deltaTime * runspeed);
2016-05-10 18:53:40 Gary_888 阅读数 1380

Unity3D射线检测控制转向,使用Ray射线检测鼠标的位置信息,角色transform方向转向该位置。

//控制转向
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;//碰撞信息,用来获取从raycast函数中得到的信息反馈的结构
        if (Physics.Raycast(ray, out hitInfo, 200, groundLayerIndex))//检测射线,控制转向
        {
            Vector3 target = hitInfo.point;
            target.y = transform.position.y;
            transform.LookAt(target);
        }

2015-11-20 16:58:09 fenrir_sun 阅读数 6134

Unity3D 角色转向和自动跟随

通过挂载脚本控制3D人物的移动和转向,先上一个官方的例子:

这里写图片描述

这里只有转向而没有移动的方法,看了下原工程,移动是做在动画中的,只要执行了动画就会跟着移动,而且每迈出一步的距离是固定的。如果移动没有做在动画里只要像旋转一样添加一个位移的变化就行了,下面是自己的例子:

代码块

以下例子仅记录下大致的方法,尚需测试,这里可以处理多个按键同时按下的情况:

using UnityEngine;

public class MoveInput
{
    bool presskey ;

    void Update() 
    {
        presskey = false;
        if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer)
        {

            bool keyboard = true;
            if (keyboard)
            {
                int x = 0;
                int y = 0;
                if (Input.GetKey(KeyCode.A))
                {
                    x -= 1;
                }
                if (Input.GetKey(KeyCode.D))
                {
                    x += 1;
                }
                if (Input.GetKey(KeyCode.S))
                {
                    y -= 1;
                }
                if (Input.GetKey(KeyCode.W))
                {
                    y += 1;
                }
                if (!GameApp.Instance().IsAutoFight() || x!=0 || y!=0 || NoTarget())
                {
                    bAutomove = false;
                    Dir2 = new Vector2(x, y);
                }
                if (x != 0 || y != 0)
                {
                    presskey = true;
                    PlayerMove(Dir2);
                }
            }
        }
    }

    void PlayerMove(Vector2 direction)
    {
        float offsetX = direction.x * Time.deltaTime * _moveToSpeed;
        float offsetY = direction.y * Time.deltaTime * _moveToSpeed;
        transform.position = new Vector3(transform.position + offsetX , 0, transform.position + offsetY );
    }
}

有时候会有一些自动跟随的需要,比如宠物跟着主角走,思路就是将主角的空间位置设置为移动目标,通过update里的迭代去接近目标,朝向也是同样处理,朝向上的接近使用:Quaternion.Slerp(self.transform.rotation, target.transform.rotation, Time.deltaTime * dirSpeed);
移动上的接近使用:Vector3.MoveTowards(self.transform.position, target.transform.position, Time.deltaTime * moveSpeed);
如果要让跟随更自然一些,可以在主角移动,每次转向的时候传给宠物一个目标,宠物按顺序将这些目标位置存放在一个列表里,按照列表里的顺序移动,就像重走了一遍主角的路线一样。

代码块

宠物跟随示例,这里仅展示下大致方法:

using UnityEngine;

public class PetMovement : BaseMovement
{
    void Update()
    {
        Player ownerPlayer = pet.OwnerPlayer;
        GameObject target = GetTarget(ownerPlayer );
        if (target != null)
        {
            float distance = Vector3.Distance(transform.position, target.transform.position);
            PetInfo petInfo = GetPetInfo(pet.ID);
            var dir = target.transform.position - transform.position;
            int skillRange = petInfo.skillRange;
            if (skillRange < distance) //  当和主人之间的距离超过技能距离时跟随
            {
                Action.ChangeAction(CAction.RunFront);// 改变动画
                var destPos = transform.position + dir.normalized * (distance - skillRange + 1);
                transform.position = Vector3.MoveTowards(transform.position, destPos, Time.deltaTime * move_Speed);
            }
            var rotation = Quaternion.LookRotation(dir); //  获得 目标方向
            transform.rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 5);  // 差值  宠物朝向趋向目标
            return;
        }
    }
}
2014-11-04 10:13:32 Braith 阅读数 1078

/// <summary>

/// Braith原创,转载请注明

/// Unity版本4.5.1f3

/// </summary>


1、

打开Unity新建立Project名称为turnround


2、

场景中Create GameObject,分别创建一个Plane,一个Cube和一盏点光源。并将点光源Point light拖放到Cube下作为子物体,这样是为了移动Cube移动灯光一起移动。

纯粹是为了有个方向分辨而已=_=b。



3、

创建一个C#脚本turnroundScript.cs并将脚本拖到场景的Cube上。Cube添加一个刚体Rigidbody。这样测试时Cube就会降落到Plane上。


4、

turnroundScript.cs的代码如下:

using UnityEngine;
using System.Collections;

public class turnroundScript : MonoBehaviour {
    private Vector3 _moveDirection  = Vector3.zero;
    private float _horizontalAxis   = 0;
    private float _verticalAxis     = 0;
	// Use this for initialization
	void Start () 
     {

	}
	
	// Update is called once per frame
	void Update () 
     {
        _horizontalAxis          = Input.GetAxis("Horizontal");//水平
        _verticalAxis            = Input.GetAxis("Vertical");//垂直
        _moveDirection           = new Vector3(_horizontalAxis, 0, _verticalAxis);
        _moveDirection.Normalize();
        this.transform.forward   = Vector3.Slerp(transform.forward, _moveDirection, 0.5f);
	}
}

比较简单的代码,主要看这一句:

this.transform.forward   = Vector3.Slerp(transform.forward, _moveDirection, 0.5f);

 transform.forward到_moveDirection,过渡速度是0.5f

this.transform.forward 指当前附加这个脚本的游戏对象的Z轴向。

 Vector3.Slerp球形插值,或叫“弧线插值”更贴切。

API手册是这样描述的

Interpolates from towards to by amount t. The returned vector's magnitude will be interpolated between magnitudes of from and to. 
通过t数值在from和to之间插值。返回的向量的长度将被插值到from到to的长度之间

static function Slerp (from : Vector3, to : Vector3, t : float) : Vector3 

5、

点击测试,键盘WSAD键控制对象方向。



本实例unitypackage下载如下

点击下载实例资源包

2017-12-03 18:21:04 A13155283231 阅读数 2308
  1. 加刚体(RigidBody) 设置 y方向锁定位置
  2. 拖拽脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RemController : MonoBehaviour {

    Vector3 movement;
    Rigidbody playerRigidbody;

    private float speed = 6f;
    private int rotSspeed = 100;


    void Awake()
    {
        playerRigidbody = GetComponent<Rigidbody>();
    }

    // 不受fps影响 因为是按一定时间间隔更新
    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        movement.Set(h, 0f, v);
        movement = movement.normalized * speed * Time.deltaTime;
        // 移动到指定位置
        playerRigidbody.MovePosition(transform.position + movement);
    }
}

只需要控制方向的移动:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RemController : MonoBehaviour {

    Vector3 movement;
    Rigidbody playerRigidbody;

    private float speed = 6f;
    public int rotSspeed = 100;


    void Awake()
    {
        playerRigidbody = GetComponent<Rigidbody>();
    }

    // 不受fps影响 因为是按一定时间间隔更新
    void FixedUpdate()
    {
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");

        //movement.Set(h, 0f, v);
        //movement = movement.normalized * speed * Time.deltaTime;
        //// 移动到指定位置
        //playerRigidbody.MovePosition(transform.position + movement);
        transform.position += transform.forward * speed * Time.deltaTime;

        if (Input.GetKey(KeyCode.A))
        {
            transform.Rotate(Vector3.up * Time.deltaTime * -rotSspeed);
        }
        if (Input.GetKey(KeyCode.D))
        {
            transform.Rotate(Vector3.up * Time.deltaTime * +rotSspeed);
        }
    }
}

Unity3D:角色控制

阅读数 581

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