国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

潛江網(wǎng)站建設(shè)如何提高搜索引擎優(yōu)化

潛江網(wǎng)站建設(shè),如何提高搜索引擎優(yōu)化,什么是wordpress靜態(tài)化,ppt超鏈接至網(wǎng)站怎么做文章目錄功能簡(jiǎn)介實(shí)現(xiàn)步驟獲取看向的位置獲取頭部的位置修改頭部的朝向限制旋轉(zhuǎn)角度超出限制范圍時(shí)自動(dòng)回正如何讓指定動(dòng)畫不受影響功能簡(jiǎn)介 如圖所示,當(dāng)相機(jī)的視角轉(zhuǎn)動(dòng)時(shí),Avatar角色的頭部會(huì)同步轉(zhuǎn)動(dòng),看向視角的方向。 實(shí)現(xiàn)步驟 獲取看向的…

文章目錄

  • 功能簡(jiǎn)介
  • 實(shí)現(xiàn)步驟
    • 獲取看向的位置
    • 獲取頭部的位置
    • 修改頭部的朝向
    • 限制旋轉(zhuǎn)角度
    • 超出限制范圍時(shí)自動(dòng)回正
  • 如何讓指定動(dòng)畫不受影響


功能簡(jiǎn)介

如圖所示,當(dāng)相機(jī)的視角轉(zhuǎn)動(dòng)時(shí),Avatar角色的頭部會(huì)同步轉(zhuǎn)動(dòng),看向視角的方向。

功能示例

實(shí)現(xiàn)步驟

獲取看向的位置

Avatar看向的位置即相機(jī)前方一定距離的某個(gè)坐標(biāo),該距離偏大于相機(jī)與Avatar角色的距離即可,可以取100來代表:

//獲取看向的位置
private Vector3 GetLookAtPosition()
{//主相機(jī)前方100個(gè)單位的位置return mainCamera.transform.position + mainCamera.transform.forward * 100f;
}

獲取頭部的位置

頭部位置可以通過Animator組件中的GetBoneTransform接口來獲取

GetBoneTransform

示例如下:

using UnityEngine;namespace SK.Framework.Avatar
{public class HeadTrack : MonoBehaviour{//動(dòng)畫組件[SerializeField] private Animator animator; private Camera mainCamera; //主相機(jī)private Transform head; //頭部private void Start(){mainCamera = Camera.main ?? FindObjectOfType<Camera>();head = animator.GetBoneTransform(HumanBodyBones.Head);}//獲取看向的位置private Vector3 GetLookAtPosition(){//主相機(jī)前方100個(gè)單位的位置return mainCamera.transform.position + mainCamera.transform.forward * 100f;}}
}

有了頭部的位置后,就可以計(jì)算頭部的高度,聲明一個(gè)變量headHeight來記錄頭部高度:

headHeight = Vector3.Distance(transform.position, head.position);

修改頭部的朝向

有了看向的坐標(biāo)和頭部的坐標(biāo),就取得了看向的朝向,在LateUpdate中賦值該頭部朝向,注意一定要使用LateUpdate,因?yàn)锳nimator動(dòng)畫組件在控制Avatar各骨骼的朝向,使用LateUpdate可以確保我們的旋轉(zhuǎn)值修改起作用。

using UnityEngine;namespace SK.Framework.Avatar
{public class HeadTrack : MonoBehaviour{//動(dòng)畫組件[SerializeField] private Animator animator; private Camera mainCamera; //主相機(jī)private Transform head; //頭部private float headHeight; //頭部的高度private void Start(){mainCamera = Camera.main ?? FindObjectOfType<Camera>();head = animator.GetBoneTransform(HumanBodyBones.Head);headHeight = Vector3.Distance(transform.position, head.position);}/// <summary>/// 看向某點(diǎn)/// </summary>/// <param name="position"></param>public void LookAtPosition(Vector3 position){//頭部位置Vector3 headPosition = transform.position + transform.up * headHeight;//朝向Quaternion lookRotation = Quaternion.LookRotation(position - headPosition);head.rotation = lookRotation;}private void LateUpdate(){Debug.DrawLine(transform.position + transform.up * headHeight, GetLookAtPosition());LookAtPosition(GetLookAtPosition());}//獲取看向的位置private Vector3 GetLookAtPosition(){//主相機(jī)前方100個(gè)單位的位置return mainCamera.transform.position + mainCamera.transform.forward * 100f;}}
}

如圖所示,我們已經(jīng)實(shí)現(xiàn)了頭部的轉(zhuǎn)向,但是旋轉(zhuǎn)值過大會(huì)導(dǎo)致反人類現(xiàn)象,因此需要將旋轉(zhuǎn)值進(jìn)行限制。

限制旋轉(zhuǎn)角度

//水平方向上的角度限制
[SerializeField] private Vector2 horizontalAngleLimit = new Vector2(-100f, 100f); //垂直方向上的角度限制
[SerializeField] private Vector2 verticalAngleLimit = new Vector2(-60f, 60f); 

封裝一個(gè)角度標(biāo)準(zhǔn)化的函數(shù),當(dāng)角度大于180度時(shí)減360度,當(dāng)角度小于180度時(shí)加360度:

//角度標(biāo)準(zhǔn)化
private float NormalizeAngle(float angle)
{if (angle > 180) angle -= 360f;else if (angle < -180) angle += 360f;return angle;
}

封裝看向某點(diǎn)的函數(shù):

/// <summary>
/// 看向某點(diǎn)
/// </summary>
/// <param name="position"></param>
public void LookAtPosition(Vector3 position)
{//頭部位置Vector3 headPosition = transform.position + transform.up * headHeight;//朝向Quaternion lookRotation = Quaternion.LookRotation(position - headPosition);Vector3 eulerAngles = lookRotation.eulerAngles - transform.rotation.eulerAngles;float x = NormalizeAngle(eulerAngles.x);float y = NormalizeAngle(eulerAngles.y);x = Mathf.Clamp(x, verticalAngleLimit.x, verticalAngleLimit.y);y = Mathf.Clamp(y, horizontalAngleLimit.x, horizontalAngleLimit.y);Quaternion rotY = Quaternion.AngleAxis(y, head.InverseTransformDirection(transform.up));head.rotation *= rotY;Quaternion rotX = Quaternion.AngleAxis(x, head.InverseTransformDirection(transform.TransformDirection(Vector3.right)));head.rotation *= rotX;
}

超出限制范圍時(shí)自動(dòng)回正

當(dāng)角度超出限制的范圍時(shí),將頭部自動(dòng)回正,可以在GetLookAtPosition函數(shù)中加入判斷,聲明autoTurnback變量標(biāo)識(shí)是否自動(dòng)回正:

//獲取看向的位置
private Vector3 GetLookAtPosition()
{Vector3 position = mainCamera.transform.position + mainCamera.transform.forward * 100f;if (!autoTurnback) return position;Vector3 direction = position - (transform.position + transform.up * headHeight);Quaternion lookRotation = Quaternion.LookRotation(direction, transform.up);Vector3 angle = lookRotation.eulerAngles - transform.eulerAngles;float x = NormalizeAngle(angle.x);float y = NormalizeAngle(angle.y);bool isInRange = x >= verticalAngleLimit.x && x <= verticalAngleLimit.y&& y >= horizontalAngleLimit.x && y <= horizontalAngleLimit.y;return isInRange ? position : (transform.position + transform.up * headHeight + transform.forward);
}

加入插值運(yùn)算,使自動(dòng)回正時(shí)有過渡過程,代碼如下:

using UnityEngine;namespace SK.Framework.Avatar
{public class HeadTrack : MonoBehaviour{[Tooltip("動(dòng)畫組件"), SerializeField] private Animator animator; [Tooltip("水平方向上的角度限制"), SerializeField] private Vector2 horizontalAngleLimit = new Vector2(-70f, 70f); [Tooltip("垂直方向上的角度限制"), SerializeField] private Vector2 verticalAngleLimit = new Vector2(-60f, 60f);[Tooltip("超出限制范圍時(shí)自動(dòng)回正"), SerializeField] private bool autoTurnback = true;[Tooltip("插值速度"), SerializeField] private float lerpSpeed = 5f;private Camera mainCamera; //主相機(jī)private Transform head; //頭部private float headHeight; //頭部的高度private float angleX;private float angleY;private void Start(){mainCamera = Camera.main ?? FindObjectOfType<Camera>();head = animator.GetBoneTransform(HumanBodyBones.Head);headHeight = Vector3.Distance(transform.position, head.position);}/// <summary>/// 看向某點(diǎn)/// </summary>/// <param name="position"></param>public void LookAtPosition(Vector3 position){//頭部位置Vector3 headPosition = transform.position + transform.up * headHeight;//朝向Quaternion lookRotation = Quaternion.LookRotation(position - headPosition);Vector3 eulerAngles = lookRotation.eulerAngles - transform.rotation.eulerAngles;float x = NormalizeAngle(eulerAngles.x);float y = NormalizeAngle(eulerAngles.y);angleX = Mathf.Clamp(Mathf.Lerp(angleX, x, Time.deltaTime * lerpSpeed), verticalAngleLimit.x, verticalAngleLimit.y);angleY = Mathf.Clamp(Mathf.Lerp(angleY, y, Time.deltaTime * lerpSpeed), horizontalAngleLimit.x, horizontalAngleLimit.y);Quaternion rotY = Quaternion.AngleAxis(angleY, head.InverseTransformDirection(transform.up));head.rotation *= rotY;Quaternion rotX = Quaternion.AngleAxis(angleX, head.InverseTransformDirection(transform.TransformDirection(Vector3.right)));head.rotation *= rotX;}//角度標(biāo)準(zhǔn)化private float NormalizeAngle(float angle){if (angle > 180) angle -= 360f;else if (angle < -180) angle += 360f;return angle;}private void LateUpdate(){LookAtPosition(GetLookAtPosition());}//獲取看向的位置private Vector3 GetLookAtPosition(){Vector3 position = mainCamera.transform.position + mainCamera.transform.forward * 100f;if (!autoTurnback) return position;Vector3 direction = position - (transform.position + transform.up * headHeight);Quaternion lookRotation = Quaternion.LookRotation(direction, transform.up);Vector3 angle = lookRotation.eulerAngles - transform.eulerAngles;float x = NormalizeAngle(angle.x);float y = NormalizeAngle(angle.y);bool isInRange = x >= verticalAngleLimit.x && x <= verticalAngleLimit.y && y >= horizontalAngleLimit.x && y <= horizontalAngleLimit.y;return isInRange ? position : (transform.position + transform.up * headHeight + transform.forward); }}
}

自動(dòng)回正

如何讓指定動(dòng)畫不受影響

如果我們想要在播放某個(gè)動(dòng)畫時(shí)不讓頭部轉(zhuǎn)動(dòng),可以通過Tag標(biāo)簽來解決,如下圖所示,為Hi動(dòng)畫增加IgnoreHeadTrack標(biāo)簽:

Tag
在代碼中加入判斷:

//獲取看向的位置
private Vector3 GetLookAtPosition()
{AnimatorStateInfo animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);if (animatorStateInfo.IsTag("IgnoreHeadTrack"))return transform.position + transform.up * headHeight + transform.forward;Vector3 position = mainCamera.transform.position + mainCamera.transform.forward * 100f;if (!autoTurnback) return position;Vector3 direction = position - (transform.position + transform.up * headHeight);Quaternion lookRotation = Quaternion.LookRotation(direction, transform.up);Vector3 angle = lookRotation.eulerAngles - transform.eulerAngles;float x = NormalizeAngle(angle.x);float y = NormalizeAngle(angle.y);bool isInRange = x >= verticalAngleLimit.x && x <= verticalAngleLimit.y&& y >= horizontalAngleLimit.x && y <= horizontalAngleLimit.y;return isInRange ? position : (transform.position + transform.up * headHeight + transform.forward);
}

完整代碼:

using UnityEngine;namespace SK.Framework.Avatar
{public class HeadTrack : MonoBehaviour{[Tooltip("動(dòng)畫組件"), SerializeField] private Animator animator; [Tooltip("水平方向上的角度限制"), SerializeField] private Vector2 horizontalAngleLimit = new Vector2(-70f, 70f); [Tooltip("垂直方向上的角度限制"), SerializeField] private Vector2 verticalAngleLimit = new Vector2(-60f, 60f);[Tooltip("超出限制范圍時(shí)自動(dòng)回正"), SerializeField] private bool autoTurnback = true;[Tooltip("插值速度"), SerializeField] private float lerpSpeed = 5f;private Camera mainCamera; //主相機(jī)private Transform head; //頭部private float headHeight; //頭部的高度private float angleX;private float angleY;private void Start(){mainCamera = Camera.main ?? FindObjectOfType<Camera>();head = animator.GetBoneTransform(HumanBodyBones.Head);headHeight = Vector3.Distance(transform.position, head.position);}/// <summary>/// 看向某點(diǎn)/// </summary>/// <param name="position"></param>public void LookAtPosition(Vector3 position){//頭部位置Vector3 headPosition = transform.position + transform.up * headHeight;//朝向Quaternion lookRotation = Quaternion.LookRotation(position - headPosition);Vector3 eulerAngles = lookRotation.eulerAngles - transform.rotation.eulerAngles;float x = NormalizeAngle(eulerAngles.x);float y = NormalizeAngle(eulerAngles.y);angleX = Mathf.Clamp(Mathf.Lerp(angleX, x, Time.deltaTime * lerpSpeed), verticalAngleLimit.x, verticalAngleLimit.y);angleY = Mathf.Clamp(Mathf.Lerp(angleY, y, Time.deltaTime * lerpSpeed), horizontalAngleLimit.x, horizontalAngleLimit.y);Quaternion rotY = Quaternion.AngleAxis(angleY, head.InverseTransformDirection(transform.up));head.rotation *= rotY;Quaternion rotX = Quaternion.AngleAxis(angleX, head.InverseTransformDirection(transform.TransformDirection(Vector3.right)));head.rotation *= rotX;}//角度標(biāo)準(zhǔn)化private float NormalizeAngle(float angle){if (angle > 180) angle -= 360f;else if (angle < -180) angle += 360f;return angle;}private void LateUpdate(){LookAtPosition(GetLookAtPosition());}//獲取看向的位置private Vector3 GetLookAtPosition(){AnimatorStateInfo animatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);if (animatorStateInfo.IsTag("IgnoreHeadTrack"))return transform.position + transform.up * headHeight + transform.forward;Vector3 position = mainCamera.transform.position + mainCamera.transform.forward * 100f;if (!autoTurnback) return position;Vector3 direction = position - (transform.position + transform.up * headHeight);Quaternion lookRotation = Quaternion.LookRotation(direction, transform.up);Vector3 angle = lookRotation.eulerAngles - transform.eulerAngles;float x = NormalizeAngle(angle.x);float y = NormalizeAngle(angle.y);bool isInRange = x >= verticalAngleLimit.x && x <= verticalAngleLimit.y && y >= horizontalAngleLimit.x && y <= horizontalAngleLimit.y;return isInRange ? position : (transform.position + transform.up * headHeight + transform.forward); }}
}
http://m.aloenet.com.cn/news/36531.html

相關(guān)文章:

  • 長(zhǎng)沙企業(yè)網(wǎng)站建設(shè)品牌廣州各區(qū)最新動(dòng)態(tài)
  • 上海網(wǎng)站關(guān)鍵字優(yōu)德國搜索引擎
  • 滎陽做網(wǎng)站推廣知乎推廣渠道
  • 海南??谧鼍W(wǎng)站軟文推廣發(fā)稿
  • 淘寶客網(wǎng)站制作教程推廣團(tuán)隊(duì)
  • 西安網(wǎng)站外包臺(tái)州做優(yōu)化
  • 好網(wǎng)站開發(fā)培訓(xùn)夜夜草
  • php無版權(quán)企業(yè)網(wǎng)站管理系統(tǒng)企業(yè)網(wǎng)站推廣外包
  • 網(wǎng)站做推廣頁需要什么軟件seo收錄查詢
  • 外貿(mào)響應(yīng)式網(wǎng)站google服務(wù)框架
  • 贛icp上饒網(wǎng)站建設(shè)seo網(wǎng)站推廣實(shí)例
  • 可以做科學(xué)模擬實(shí)驗(yàn)的網(wǎng)站百度指數(shù)怎么查詢
  • c語言做網(wǎng)站賬號(hào)登錄系統(tǒng)銷售網(wǎng)站有哪些
  • 網(wǎng)站提交百度收錄怎么簡(jiǎn)單制作一個(gè)網(wǎng)頁
  • 學(xué)校網(wǎng)站的建設(shè)目標(biāo)是什么今天的熱搜榜
  • 網(wǎng)站開發(fā)多少錢一個(gè)網(wǎng)站推廣優(yōu)化價(jià)格
  • 源碼網(wǎng)站程序指數(shù)函數(shù)求導(dǎo)公式
  • 濟(jì)南品牌營銷型網(wǎng)站建設(shè)品牌策劃運(yùn)營公司
  • 怎么編網(wǎng)站中央廣播電視總臺(tái)
  • 林州網(wǎng)站建設(shè)慈溪seo
  • 空調(diào)設(shè)備公司網(wǎng)站建設(shè)上海城市分站seo
  • 文化傳媒公司網(wǎng)站建設(shè)seo排名點(diǎn)擊工具
  • 如何寫好網(wǎng)站文案站長(zhǎng)之家官網(wǎng)入口
  • 龍華做棋牌網(wǎng)站建設(shè)多少錢廣告聯(lián)盟接廣告
  • wordpress文章點(diǎn)贊旺道seo優(yōu)化軟件怎么用
  • 獨(dú)立站shopify需要費(fèi)用嗎查關(guān)鍵詞排名工具app
  • 做門戶網(wǎng)站需要具備什么yw77731域名查詢
  • 深廣縱橫設(shè)計(jì)公司官網(wǎng)北京seo顧問服務(wù)
  • 公司備案查詢網(wǎng)站備案成都網(wǎng)站快速優(yōu)化排名
  • 濰坊網(wǎng)站建設(shè)最新報(bào)價(jià)steam交易鏈接在哪看