關於Unity中ARPG遊戲人物移動

來源:互聯網
上載者:User

標籤:star   unity   就會   相關   date   for   color   執行個體   oid   

ARPG:動作型角色扮演類遊戲

大多數的ARPG遊戲都是使用搖杆操作,以第三人稱攝像機的方式來跟隨主角,實際上人物只走八個方向,上,下,左,右,左上,左下,右下,右上

 

 

控制角色移動的思路
1: 在ARPG遊戲中,主角人物在搖杆下控制行走;
2: 主角人物遇到障礙物(碰撞器)將不會穿越過去;
3: 搖杆控制主角人物8個方向的行走;
4: 使用CharacterController 角色控制器組件: 讓你在受制於碰撞的情況下很容易的進行運動,而不用處理剛體,實際上沒有剛體的物理特性。角色控制器不受力的影響,僅當你調用Move函數時才運動。它執行運動,但是受制於其他碰撞器。

 本來以前都是在角色上面掛載剛體(用裡面的重力)和碰撞器組件,如果碰到其他的剛體還會受力會受到一些不好的影響,用了CharacterController 就不會有這種不相關的物理力的影響了。
5: 調用角色控制器的Move函數移動角色;
6: 根據搖杆的方向旋轉人物動畫;

 

 

CharacterController組件

1: 屬性面板屬性:
  Slope Limit: 角色碰撞器只能爬比這個指定角度低的斜坡:(單位是degree)
  Step Offset: 上樓梯模式,小於Step Offset 的台階,可以直接上去;
  Skin Width: 兩個碰撞器可以互相滲透深入皮膚寬度,一般設定成radius的10%;
  Min Move Distance: 調用Move函數移動的最小移動量,如果移動距離比這個小,將不移動;
  center: 相對與transform的位置角色叫膠囊體中心;
  height: 膠囊體高度;
  Radius: 膠囊體的半徑;
2: 碰撞檢測:
  void OnControllerColliderHit(ControllerColliderHit hit) {},和一般的碰撞器一樣。有碰撞後會調用這個介面。只會在和其他帶有CharacterController組件的物體發生碰撞時才調用。
3: 重要方法:
  Move(Vec3 offset): 移動的距離;

  如果一個角色掛載了CharacterController組件。那麼要控制這個角色的移動,其實不必改變角色節點的位置,只需對這個組件進行Move操作,角色就會跟著走。

  我把這個組件理解為一個可以牽動節點的可以設定特殊移動屬性的膠囊體碰撞器組件Capsule Collider

 

 

遙杆編寫的基本思路與原理 

1:以8個方向為例,將整個圓分為 下,右下,右,右上,上,左上, 左, 左下;
2:當我們的遙感中心點位於某一個方向的範圍內,那麼就屬於這個方向;

3.排除一個無效的搖杆地區,在這個地區內主角不會跟著移動

4.角色移動的距離是一個標量,等於速度乘於時間,而角色移動的整個行為是一個向量,所以還要考慮方向,獲得搖杆的角度得知運動方向後還要把角色到最終目的地的標量距離分解成X和Z軸方向上的距離。

根據搖杆的方向算出當前距離所對應的向量的分解的係數

 

 

執行個體

1.建立Unity工程項目和檔案目錄

2.匯入人物模型資源和地圖資源,以及搖杆包(79)

3.人物模型的材質球shader使用Mobile Diffuse,關聯好貼圖,設定模型---->Rig---->Animation Type---->Legacy---->Apply

4.在人物模型的Animation裡添加跑動的動畫,136-161幀是跑動的幀,Wrap Mode---->Loop---->Apply,角色配置完畢,拖進情境中

5.建立一個平面Plane,關聯材質,放大10倍

6.不需要添加碰撞器,只要給主角添加CharacterController組件,調整組件的膠囊體到完全蓋住主角,它有碰撞地區但是不受力的影響。

7.添加搖杆,Hedgehog Team---->Easy Touch---->Add Easy Touch For C#,Hedgehog Team---->Easy Touch---->Extension---->Adding a new joystick

8.調整攝像機的位置,到可以看見主角運動的最佳位置

9.在主角下面掛載一個指令碼Person來通過搖杆控制角色移動

 Person.cs

using System.Collections;using System.Collections.Generic;using UnityEngine;enum DIR//定義一個枚舉來區分角色移動的八個方向{    INVALID_DIR = -1,    UP = 0,    DOWN = 1,    LEFT = 2,    RIGHT = 3,    RU = 4,    LU = 5,    LD = 6,    RD = 7,}public class person : MonoBehaviour{    float move_speed = 8.0f;//角色移動速度    CharacterController c_ctrl;//角色控制器組件    public EasyJoystick joystick;//搖杆    float[] x_set;//八個方向在X軸上的分解係數    float[] z_set;//八個方向在Z軸上的分解係數    float[] rot_set;//人物面的朝向的角度表    Vector3 camera_offset;    // Use this for initialization    void Start()    {        this.c_ctrl = this.GetComponent<CharacterController>();        //按照上,下,左,右,右上,左上,左下,右下的順序配置        this.x_set = new float[8] { 0, 0, -1, 1, 0.707f, -0.707f, -0.707f, 0.707f };//cos45=0.707,sin45=0.707        this.z_set = new float[8] { 1, -1, 0, 0, 0.707f, 0.707f, -0.707f, -0.707f };        this.rot_set = new float[8] { 0, 180, -90, 90, 45, -45, -135, 135 };        this.camera_offset = Camera.main.transform.position - this.transform.position;//擷取當前攝像機和人物的三維距離    }    int get_dir(float r)    {        if (r >= -Mathf.PI && r < -7 * Mathf.PI / 8)        { // 左的一部分            return (int)DIR.LEFT;        }        else if (r >= -7 * Mathf.PI / 8 && r < -5 * Mathf.PI / 8)        {//左下            return (int)DIR.LD;        }        else if (r >= -5 * Mathf.PI / 8 && r < -3 * Mathf.PI / 8)        {//下            return (int)DIR.DOWN;        }        else if (r >= -3 * Mathf.PI / 8 && r < -1 * Mathf.PI / 8)        {//右下            return (int)DIR.RD;        }        else if (r >= -1 * Mathf.PI / 8 && r < 1 * Mathf.PI / 8)        {//右            return (int)DIR.RIGHT;        }        else if (r >= 1 * Mathf.PI / 8 && r < 3 * Mathf.PI / 8)        {//右上            return (int)DIR.RU;        }        else if (r >= 3 * Mathf.PI / 8 && r < 5 * Mathf.PI / 8)        {//上            return (int)DIR.UP;        }        else if (r >= 5 * Mathf.PI / 8 && r < 7 * Mathf.PI / 8)        {//左上            return (int)DIR.LU;        }        else if (r >= 7 * Mathf.PI / 8 && r < 8 * Mathf.PI / 8)        {//左的另一部分            return (int)DIR.LEFT;        }        return (int)DIR.INVALID_DIR;//無效的地區    }    void walk_update()    {        float x = this.joystick.JoystickTouch.x;//搖杆座標系的X座標        float y = this.joystick.JoystickTouch.y;//搖杆座標系的Y座標        float len = (x * x + y * y);//不開根號是因為開銷太大,而且是在Update裡面,每幀都開根號受不了        if (len < (0.5f * 0.5f))//搖杆移動到這片地區是無效的        {            return;        }        // 擷取這個方向        float r = Mathf.Atan2(y, x); // 使用反三角函數, 擷取向量的角度, [-PI, PI]        int dir = this.get_dir(r);        if (dir != (int)DIR.INVALID_DIR)        {            float s = this.move_speed * Time.deltaTime;//每一秒要移動的距離            Vector3 offset = new Vector3(s * this.x_set[dir], 0, s * this.z_set[dir]);//把這個距離分解到X和Z方向上            this.c_ctrl.Move(offset);//每一幀都移動            // 切換人物行走的朝向            Vector3 e_rot = this.transform.eulerAngles;            e_rot.y = this.rot_set[dir];            this.transform.eulerAngles = e_rot;            // end         }        // end     }    // Update is called once per frame    void Update()    {        this.walk_update();        Camera.main.transform.position = this.transform.position + this.camera_offset;//保持人物和攝像機的距離不變    }}

10.運行效果

關於Unity中ARPG遊戲人物移動

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.