[Unity3D] 技能釋放方向指示的一種實(shí)現(xiàn)方式(移動(dòng)平臺(tái))

基本原理:通過Input.GetTouch().position,獲得觸摸位置并根據(jù)手指移動(dòng)方向來(lái)計(jì)算出技能釋放方向,然后通過LIneRenderer生成方向指示線,實(shí)現(xiàn)類似于《王者榮耀》指向性技能釋放時(shí)的方向指示效果。

void Update(){
    
    //假設(shè)觸摸點(diǎn)1正在用于控制角色方向;觸摸點(diǎn)2位于屏幕右側(cè),該側(cè)有技能按鈕;
    if (Input.touchCount>0 && Input.GetTouch(1).position.x > Screen.width/2) {
        
        //觸摸點(diǎn)2被觸碰
        if (Input.GetTouch(1).phase == TouchPhase.Began)
        {
            //獲得第二個(gè)觸摸點(diǎn)的位置,并保存,將用作計(jì)算相對(duì)位置的基點(diǎn)
            m_DragStartPoint = Input.GetTouch(1).position;
        }
        // 觸摸點(diǎn)2在移動(dòng)
        if (Input.GetTouch(1).phase == TouchPhase.Moved)
        {
            // 根據(jù)觸摸點(diǎn)2的位置,計(jì)算需要的方向向量;
            CalDir(Input.GetTouch(1).position);
            // 計(jì)算全局坐標(biāo)系下的Z方向至上一步得到的方向向量的夾角;
            m_rotAngle = AngleBetweenVector3(Vector3.forward, m_TouchDeltaDir);
            // 調(diào)用LineRenderer繪制線段
            DrawLine (m_LineStartPosition.position,m_LineEnd);
            // 根據(jù)該夾角,計(jì)算技能釋放時(shí)所需的旋轉(zhuǎn)Quanternion
            m_SpellRotation = Quaternion.Euler(0,m_rotAngle,0);
            
        //觸摸點(diǎn)2保持靜止  
        }else if(Input.GetTouch(1).phase == TouchPhase.Stationary){
            // 這一步原理同上,用于確保角色移動(dòng)時(shí)線段的起點(diǎn)能夠與角色同步
            CalDir(Input.GetTouch(1).position);
            DrawLine (m_LineStartPosition.position,m_LineEnd);
        
        //觸摸點(diǎn)2終止,手指離開屏幕 
        }else if(Input.GetTouch(1).phase == TouchPhase.Ended){
            // 這里調(diào)用你的技能,實(shí)現(xiàn)技能釋放;
            // 由于這里用了ParitcleSystem作為被釋放的技能,對(duì)應(yīng)的transform在初始化時(shí)無(wú)Rotation,也就是transform.forward與Vector3.forward一致,因此,在釋放技能時(shí),需要將之前得到的Quanterniou作為參數(shù),在ParticleSystem生成時(shí)便旋轉(zhuǎn)至與方向指示線一致的方向。
            m_Spell.SpellCast (1,m_SpellRotation,0);
            
            //停止線段繪制;
            DropLine();
        }

        //DrawLine (m_LineStartPosition.position,m_LineEnd);
    }
}

void CalDir(Vector2 touchposition){
    // 計(jì)算自初始觸摸位置至當(dāng)前觸摸位置的向量
    m_TouchDeltaPosition = touchposition - m_DragStartPoint;
    // 注意: Input.Touch().Position 得到的是Vector2;
    // 將Vector2 轉(zhuǎn)化為Vector3,由于是在X-Z平面繪制,所以Y方向?yàn)?;
    m_TouchDeltaDir = new Vector3(m_TouchDeltaPosition.x, 0, m_TouchDeltaPosition.y);
    // 上一步得到一個(gè)在全局坐標(biāo)系下,觸摸位置相對(duì)于基點(diǎn)的方向向量;
    // 接下來(lái)便可以利用這個(gè)方向向量,從角色的位置畫出一條直線作為技能釋放方向的指示。
    
    // 計(jì)算直線的繪制終點(diǎn)
    m_LineEnd = m_LineStartPosition.position + m_TouchDeltaDir.normalized * 10f;
}

float AngleBetweenVector3(Vector3 vec1, Vector3 vec2){

    float sign = (vec2.x < vec1.x) ? -1.0f : 1.0f;
    return (Vector3.Angle (vec1,vec2) ) * sign;
}

void DrawLine(Vector3 start,Vector3 end){
    if (!GetComponent<LineRenderer> ()) {
        m_LineRenderer = gameObject.AddComponent<LineRenderer> ();
    }

    m_LineRenderer.enabled = true;
    m_LineRenderer.startColor = Color.red;
    m_LineRenderer.endColor = Color.red;
    m_LineRenderer.startWidth = 0.2f;
    m_LineRenderer.endWidth = 0.2f;
    m_LineRenderer.SetPosition (0,start);
    m_LineRenderer.SetPosition (1,end);
    
}

void DropLine(){
    if (!GetComponent<LineRenderer> ()) {
        return;
    } else {
        m_LineRenderer.enabled = false;
    }
}

//m_Spell.SpellCast
public void SpellCast(...){
    ...
    // m_Spell 對(duì)應(yīng)所釋放的技能,是一個(gè)以ParticleSystem為基礎(chǔ)的特效;
    // SpellCastPosition 是技能釋放位置,也就是ParticleSystem開始的位置;
    // m_SpellRotation 是ParticleSystem的旋轉(zhuǎn)量;
    GameObject spell = (GameObject)Instantiate (m_Spell, SpellCastPosition, m_SpellRotation);
    ...
}

做完之后的效果就是下面這個(gè)樣子,這條線雖然看起來(lái)很丑,但是用來(lái)瞄準(zhǔn)還是很實(shí)用的。

技能方向 (1).gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容