iphone 被攻击抹掉上控制4个职业一起打怪的游戏 人物会自动攻击 用手指拖动人物选择目标 比较卡通的

Unity3D代码(18)
Unity3D日常(44)
Unity3D插件(4)
官方自带的资源包
首先是下载地址
5.0.0f4版本的官方自带资源包
2017斑斑的官方自带资源包
有的就不用下载了,如果没有的话下载下载 ,放在
xx\Editor路径下面,重新打开Unity3d就有了
Assets-&Standard Assets -&Characters -&FirstPersonCharacter -&Prefabs
选择预制体拖入到场景中就可以使用了
有两个预制体
FPSController
主要组件有Character Controller、脚本First Person Controller、Rigidbody
这个是FPS第一人称控制器,模拟FPS游戏中人物移动的方式,是第一人称控制器。
鼠标锁定,视角跟随鼠标移动而移动。WSAD控制人物移动
RigidBodyFPSController
主要组件有Capsule Collider、脚本RigidBody First Person Controller
与FPSController控制器不同的一点是,一个是用CharacterController控制移动,一个是控制人物本身的刚体,给刚体添加一个方向力,就可以移动
详细解析脚本
First Person Controller
using UnityE
using UnityStandardAssets.CrossPlatformI
using UnityStandardAssets.U
using Random = UnityEngine.R
namespace UnityStandardAssets.Characters.FirstPerson
[RequireComponent(typeof (CharacterController))]
[RequireComponent(typeof (AudioSource))]
public class FirstPersonController : MonoBehaviour
[SerializeField] private bool m_IsW
[SerializeField] private float m_WalkS
[SerializeField] private float m_RunS
[SerializeField] [Range(0f, 1f)] private float m_RunstepL
[SerializeField] private float m_JumpS
[SerializeField] private float m_StickToGroundF
[SerializeField] private float m_GravityM
[SerializeField] private MouseLook m_MouseL
[SerializeField] private bool m_UseFovK
[SerializeField] private FOVKick m_FovKick = new FOVKick();
[SerializeField] private bool m_UseHeadB
[SerializeField] private CurveControlledBob m_HeadBob = new CurveControlledBob();
[SerializeField] private LerpControlledBob m_JumpBob = new LerpControlledBob();
[SerializeField] private float m_StepI
[SerializeField] private AudioClip[] m_FootstepS
[SerializeField] private AudioClip m_JumpS
[SerializeField] private AudioClip m_LandS
private Camera m_C
private bool m_J
private float m_YR
private Vector2 m_I
private Vector3 m_MoveDir = Vector3.
private CharacterController m_CharacterC
private CollisionFlags m_CollisionF
private bool m_PreviouslyG
private Vector3 m_OriginalCameraP
private float m_StepC
private float m_NextS
private bool m_J
private AudioSource m_AudioS
private void Start()
m_CharacterController = GetComponent&CharacterController&();
m_Camera = Camera.
m_OriginalCameraPosition = m_Camera.transform.localP
m_FovKick.Setup(m_Camera);
m_HeadBob.Setup(m_Camera, m_StepInterval);
m_StepCycle = 0f;
m_NextStep = m_StepCycle/2f;
m_Jumping = false;
m_AudioSource = GetComponent&AudioSource&();
m_MouseLook.Init(transform , m_Camera.transform);
private void Update()
RotateView();
if (!m_Jump)
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
if (!m_PreviouslyGrounded && m_CharacterController.isGrounded)
StartCoroutine(m_JumpBob.DoBobCycle());
PlayLandingSound();
m_MoveDir.y = 0f;
m_Jumping = false;
if (!m_CharacterController.isGrounded && !m_Jumping && m_PreviouslyGrounded)
m_MoveDir.y = 0f;
m_PreviouslyGrounded = m_CharacterController.isG
private void PlayLandingSound()
m_AudioSource.clip = m_LandS
m_AudioSource.Play();
m_NextStep = m_StepCycle + .5f;
private void FixedUpdate()
GetInput(out speed);
Vector3 desiredMove = transform.forward*m_Input.y + transform.right*m_Input.x;
RaycastHit hitI
Physics.SphereCast(transform.position, m_CharacterController.radius, Vector3.down, out hitInfo,
m_CharacterController.height/2f);
desiredMove = Vector3.ProjectOnPlane(desiredMove, hitInfo.normal).
m_MoveDir.x = desiredMove.x*
m_MoveDir.z = desiredMove.z*
if (m_CharacterController.isGrounded)
m_MoveDir.y = -m_StickToGroundF
if (m_Jump)
m_MoveDir.y = m_JumpS
PlayJumpSound();
m_Jump = false;
m_Jumping = true;
m_MoveDir += Physics.gravity*m_GravityMultiplier*Time.fixedDeltaT
m_CollisionFlags = m_CharacterController.Move(m_MoveDir*Time.fixedDeltaTime);
ProgressStepCycle(speed);
UpdateCameraPosition(speed);
private void PlayJumpSound()
m_AudioSource.clip = m_JumpS
m_AudioSource.Play();
private void ProgressStepCycle(float speed)
if (m_CharacterController.velocity.sqrMagnitude & 0 && (m_Input.x != 0 || m_Input.y != 0))
m_StepCycle += (m_CharacterController.velocity.magnitude + (speed*(m_IsWalking ? 1f : m_RunstepLenghten)))*
Time.fixedDeltaT
if (!(m_StepCycle & m_NextStep))
m_NextStep = m_StepCycle + m_StepI
PlayFootStepAudio();
private void PlayFootStepAudio()
if (!m_CharacterController.isGrounded)
int n = Random.Range(1, m_FootstepSounds.Length);
m_AudioSource.clip = m_FootstepSounds[n];
m_AudioSource.PlayOneShot(m_AudioSource.clip);
m_FootstepSounds[n] = m_FootstepSounds[0];
m_FootstepSounds[0] = m_AudioSource.
private void UpdateCameraPosition(float speed)
Vector3 newCameraP
if (!m_UseHeadBob)
if (m_CharacterController.velocity.magnitude & 0 && m_CharacterController.isGrounded)
m_Camera.transform.localPosition =
m_HeadBob.DoHeadBob(m_CharacterController.velocity.magnitude +
(speed*(m_IsWalking ? 1f : m_RunstepLenghten)));
newCameraPosition = m_Camera.transform.localP
newCameraPosition.y = m_Camera.transform.localPosition.y - m_JumpBob.Offset();
newCameraPosition = m_Camera.transform.localP
newCameraPosition.y = m_OriginalCameraPosition.y - m_JumpBob.Offset();
m_Camera.transform.localPosition = newCameraP
private void GetInput(out float speed)
float horizontal = CrossPlatformInputManager.GetAxis("Horizontal");
float vertical = CrossPlatformInputManager.GetAxis("Vertical");
bool waswalking = m_IsW
#if !MOBILE_INPUT
m_IsWalking = !Input.GetKey(KeyCode.LeftShift);
speed = m_IsWalking ? m_WalkSpeed : m_RunS
m_Input = new Vector2(horizontal, vertical);
if (m_Input.sqrMagnitude & 1)
m_Input.Normalize();
if (m_IsWalking != waswalking && m_UseFovKick && m_CharacterController.velocity.sqrMagnitude & 0)
StopAllCoroutines();
StartCoroutine(!m_IsWalking ? m_FovKick.FOVKickUp() : m_FovKick.FOVKickDown());
private void RotateView()
m_MouseLook.LookRotation (transform, m_Camera.transform);
private void OnControllerColliderHit(ControllerColliderHit hit)
Rigidbody body = hit.collider.attachedR
if (m_CollisionFlags == CollisionFlags.Below)
if (body == null || body.isKinematic)
body.AddForceAtPosition(m_CharacterController.velocity*0.1f, hit.point, ForceMode.Impulse);
主要的人物移动代码
m_CollisionFlags = m_CharacterController.Move(m_MoveDir*Time.fixedDeltaTime)
m_CollisionFlags 碰撞检测的旗标
m_CharacterController 角色的CharacterController组件
m_MoveDir 当前移动的方向乘上键盘获得的输入得到的值
Time.fixedDeltaTime 固定的时间增量
其中如果要解除鼠标锁定的话可以到这个脚本中修改
public void UpdateCursorLock()
if (lockCursor)
InternalLockUpdate();
private void InternalLockUpdate()
if (Input.GetKeyUp(KeyCode.Escape))
m_cursorIsLocked = false;
else if (Input.GetMouseButtonUp(1))
m_cursorIsLocked = true;
if (m_cursorIsLocked)
Cursor.lockState = CursorLockMode.L
Cursor.visible = false;
else if (!m_cursorIsLocked)
Cursor.lockState = CursorLockMode.N
Cursor.visible = true;
RigidbodyFirstPersonController
using UnityE
using UnityStandardAssets.CrossPlatformI
namespace UnityStandardAssets.Characters.FirstPerson
[RequireComponent(typeof (Rigidbody))]
[RequireComponent(typeof (CapsuleCollider))]
public class RigidbodyFirstPersonController : MonoBehaviour
[Serializable]
public class MovementSettings
public float ForwardSpeed = 8.0f;
public float BackwardSpeed = 4.0f;
public float StrafeSpeed = 4.0f;
public float RunMultiplier = 2.0f;
public KeyCode RunKey = KeyCode.LeftS
public float JumpForce = 30f;
public AnimationCurve SlopeCurveModifier = new AnimationCurve(new Keyframe(-90.0f, 1.0f), new Keyframe(0.0f, 1.0f), new Keyframe(90.0f, 0.0f));
[HideInInspector] public float CurrentTargetSpeed = 8f;
#if !MOBILE_INPUT
private bool m_R
public void UpdateDesiredTargetSpeed(Vector2 input)
if (input == Vector2.zero) return;
if (input.x & 0 || input.x & 0)
CurrentTargetSpeed = StrafeS
if (input.y & 0)
CurrentTargetSpeed = BackwardS
if (input.y & 0)
CurrentTargetSpeed = ForwardS
#if !MOBILE_INPUT
if (Input.GetKey(RunKey))
CurrentTargetSpeed *= RunM
m_Running = true;
m_Running = false;
#if !MOBILE_INPUT
public bool Running
get { return m_R }
[Serializable]
public class AdvancedSettings
public float groundCheckDistance = 0.01f;
public float stickToGroundHelperDistance = 0.5f;
public float slowDownRate = 20f;
public bool airC
public MovementSettings movementSettings = new MovementSettings();
public MouseLook mouseLook = new MouseLook();
public AdvancedSettings advancedSettings = new AdvancedSettings();
private Rigidbody m_RigidB
private CapsuleCollider m_C
private float m_YR
private Vector3 m_GroundContactN
private bool m_Jump, m_PreviouslyGrounded, m_Jumping, m_IsG
public Vector3 Velocity
get { return m_RigidBody. }
public bool Grounded
get { return m_IsG }
public bool Jumping
get { return m_J }
public bool Running
#if !MOBILE_INPUT
return movementSettings.R
return false;
private void Start()
m_RigidBody = GetComponent&Rigidbody&();
m_Capsule = GetComponent&CapsuleCollider&();
mouseLook.Init (transform, cam.transform);
private void Update()
RotateView();
if (CrossPlatformInputManager.GetButtonDown("Jump") && !m_Jump)
m_Jump = true;
private void FixedUpdate()
GroundCheck();
Vector2 input = GetInput();
if ((Mathf.Abs(input.x) & float.Epsilon || Mathf.Abs(input.y) & float.Epsilon) && (advancedSettings.airControl || m_IsGrounded))
Vector3 desiredMove = cam.transform.forward*input.y + cam.transform.right*input.x;
desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).
desiredMove.x = desiredMove.x*movementSettings.CurrentTargetS
desiredMove.z = desiredMove.z*movementSettings.CurrentTargetS
desiredMove.y = desiredMove.y*movementSettings.CurrentTargetS
if (m_RigidBody.velocity.sqrMagnitude &
(movementSettings.CurrentTargetSpeed*movementSettings.CurrentTargetSpeed))
m_RigidBody.AddForce(desiredMove*SlopeMultiplier(), ForceMode.Impulse);
if (m_IsGrounded)
m_RigidBody.drag = 5f;
if (m_Jump)
m_RigidBody.drag = 0f;
m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
m_Jumping = true;
if (!m_Jumping && Mathf.Abs(input.x) & float.Epsilon && Mathf.Abs(input.y) & float.Epsilon && m_RigidBody.velocity.magnitude & 1f)
m_RigidBody.Sleep();
m_RigidBody.drag = 0f;
if (m_PreviouslyGrounded && !m_Jumping)
StickToGroundHelper();
m_Jump = false;
private float SlopeMultiplier()
float angle = Vector3.Angle(m_GroundContactNormal, Vector3.up);
return movementSettings.SlopeCurveModifier.Evaluate(angle);
private void StickToGroundHelper()
RaycastHit hitI
if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
((m_Capsule.height/2f) - m_Capsule.radius) +
advancedSettings.stickToGroundHelperDistance))
if (Mathf.Abs(Vector3.Angle(hitInfo.normal, Vector3.up)) & 85f)
m_RigidBody.velocity = Vector3.ProjectOnPlane(m_RigidBody.velocity, hitInfo.normal);
private Vector2 GetInput()
Vector2 input = new Vector2
x = CrossPlatformInputManager.GetAxis("Horizontal"),
y = CrossPlatformInputManager.GetAxis("Vertical")
movementSettings.UpdateDesiredTargetSpeed(input);
private void RotateView()
if (Mathf.Abs(Time.timeScale) & float.Epsilon) return;
float oldYRotation = transform.eulerAngles.y;
mouseLook.LookRotation (transform, cam.transform);
if (m_IsGrounded || advancedSettings.airControl)
Quaternion velRotation = Quaternion.AngleAxis(transform.eulerAngles.y - oldYRotation, Vector3.up);
m_RigidBody.velocity = velRotation*m_RigidBody.
sphere cast down just beyond the bottom of the capsule to see if the capsule is colliding round the bottom
private void GroundCheck()
m_PreviouslyGrounded = m_IsG
RaycastHit hitI
if (Physics.SphereCast(transform.position, m_Capsule.radius, Vector3.down, out hitInfo,
((m_Capsule.height/2f) - m_Capsule.radius) + advancedSettings.groundCheckDistance))
m_IsGrounded = true;
m_GroundContactNormal = hitInfo.
m_IsGrounded = false;
m_GroundContactNormal = Vector3.
if (!m_PreviouslyGrounded && m_IsGrounded && m_Jumping)
m_Jumping = false;
主要的人物移动代码
m_RigidBody.AddForce(desiredMove*SlopeMultiplier(), ForceMode.Impulse)
desiredMove 这个是获取到摄像机正前方 x 键盘输入 Vertical的值
摄像机右边 x 键盘输入 Horizontal的值
SlopeMuliplier 是斜率乘数
说白了就是摩擦力 反作用力
ForceMode 作用力方式 枚举类型
(1)ForceMode.Force:默认方式,使用刚体的质量计算,以每帧间隔时间为单位计算动量。
(2)ForceMode.Acceleration:在此种作用方式下会忽略刚体的实际质量而采用默认值1.0f,时间间隔以系统帧频间隔计算(默认值为0.02s)
(3)ForceMode.Impulse:此种方式采用瞬间力作用方式,即把t的值默认为1,不再采用系统的帧频间隔
(4)ForceMode.VelocityChange:此种作用方式下将忽略刚体的实际质量,采用默认质量1.0,同时也忽略系统的实际帧频间隔,采用默认间隔1.0
接下来是官方第一人称控制器的自带的摇杆
接下来介绍这几种预制体
CarTiltControls
用于赛车游戏的跨平台输入控制。可选择两种输入形式:
  一,Vertical轴输入值由一对按钮控制,Horizontal轴输入值由设备重力感应控制(目标平台为PC时使用鼠标位置模拟,下同);
  二,两个方向的输入值均由触屏滑动(移动设备)或鼠标拖拽(PC)控制。
DualTouchControls
下面是TouchPad代码
using UnityE
using UnityEngine.EventS
using UnityEngine.UI;
namespace UnityStandardAssets.CrossPlatformInput
[RequireComponent(typeof(Image))]
public class TouchPad : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
public enum AxisOption
OnlyHorizontal,
OnlyVertical
public enum ControlStyle
public AxisOption axesToUse = AxisOption.B
public ControlStyle controlStyle = ControlStyle.A
public string horizontalAxisName = "Horizontal";
public string verticalAxisName = "Vertical";
public float Xsensitivity = 1f;
public float Ysensitivity = 1f;
Vector3 m_StartP
Vector2 m_PreviousD
Vector3 m_JoytickO
bool m_UseX;
bool m_UseY;
CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualA
CrossPlatformInputManager.VirtualAxis m_VerticalVirtualA
int m_Id = -1;
Vector2 m_PreviousTouchP
#if !UNITY_EDITOR
private Vector3 m_C
private Image m_I
Vector3 m_PreviousM
void OnEnable()
CreateVirtualAxes();
#if !UNITY_EDITOR
m_Image = GetComponent&Image&();
m_Center = m_Image.transform.
void CreateVirtualAxes()
m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);
if (m_UseX)
m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
if (m_UseY)
m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
void UpdateVirtualAxes(Vector3 value)
value = value.
if (m_UseX)
m_HorizontalVirtualAxis.Update(value.x);
if (m_UseY)
m_VerticalVirtualAxis.Update(value.y);
public void OnPointerDown(PointerEventData data)
m_Dragging = true;
m_Id = data.pointerId;
#if !UNITY_EDITOR
if (controlStyle != ControlStyle.Absolute )
m_Center = data.
void Update()
if (!m_Dragging)
if (Input.touchCount == 2)
if (Input.GetTouch(0).phase == TouchPhase.Moved || Input.GetTouch(1).phase == TouchPhase.Moved)
var tempPosition1 = Input.GetTouch(0).
var tempPosition2 = Input.GetTouch(1).
float sprtTemp = Mathf.Sqrt((tempPosition1.x - tempPosition2.x) * (tempPosition1.x - tempPosition2.x) + (tempPosition1.y - tempPosition2.y) * (tempPosition1.y - tempPosition2.y));
if (Input.touchCount &= m_Id + 1 && m_Id != -1)
#if !UNITY_EDITOR
if (controlStyle == ControlStyle.Swipe)
m_Center = m_PreviousTouchP
m_PreviousTouchPos = Input.touches[m_Id].
Vector2 pointerDelta = new Vector2(Input.touches[m_Id].position.x - m_Center.x , Input.touches[m_Id].position.y - m_Center.y).
pointerDelta.x *= X
pointerDelta.y *= Y
Vector2 pointerD
pointerDelta.x = Input.mousePosition.x - m_PreviousMouse.x;
pointerDelta.y = Input.mousePosition.y - m_PreviousMouse.y;
m_PreviousMouse = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0f);
UpdateVirtualAxes(new Vector3(pointerDelta.x, pointerDelta.y, 0));
public void OnPointerUp(PointerEventData data)
m_Dragging = false;
m_Id = -1;
UpdateVirtualAxes(Vector3.zero);
void OnDisable()
if (CrossPlatformInputManager.AxisExists(horizontalAxisName))
CrossPlatformInputManager.UnRegisterVirtualAxis(horizontalAxisName);
if (CrossPlatformInputManager.AxisExists(verticalAxisName))
CrossPlatformInputManager.UnRegisterVirtualAxis(verticalAxisName);
左边手指滑动可以控制行走
右边手指滑动可以控制视角转动
Jump就是跳
演示了多点触控情景下TouchPad脚本的使用方式,通过将不同区域的滑动或拖拽数据映射到不同的虚拟轴来避免冲突。
MobileAircraftControls
 用于飞行器的跨平台输入控制。主要演示了ButtonHandler脚本的使用,自动将触控或鼠标指针的按下和抬起映射为特定虚拟轴的状态变化。同时将重力感应数据映射为横向和纵向输入值。
MoblieSingleStickControl
主要演示Joystick脚本的使用,通过滑动或拖拽控制输入,与TouchPad的区别在于
MobileJoystick的使用是根据手指拖动的距离来移动
而TouchPad是与上一帧位置间的距离作为输入值
MobileTiltControlRig
无UI元素,可在代码中通过CrossPlatformInputManager获取其映射轴的值,输入来源为重力感应数据(移动平台)或鼠标位置(PC)。
摇杆使用的注意事项
首先如果不是在安卓平台的话,直接把预制体拖入层级视图Hierarchy是不会显示的
首先切换成安卓平台 File-&BUild Settings-&选中安卓平台Android-&Switch platform就行了
然后把预制体拖入到层级视图里面就显示了
最后附上一段Joystick脚本在不同方向显示不同sprite的代码
也就是人们常说的八方向控制摇杆移动的方法
判断角度控制摇杆移动
Joystick脚本,这个脚本我已经修改过了,加了一个8个方向显示不同的Sprite的效果
using UnityE
using UnityEngine.EventS
using UnityEngine.UI;
namespace UnityStandardAssets.CrossPlatformInput
public class Joystick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
public Sprite[] sourceI
private Image mobileJoystickI
private Image arrowI
private Image backgroundI
public Material[] materialsI
public enum AxisOption
OnlyHorizontal,
OnlyVertical
public int MovementRange = 100;
public AxisOption axesToUse = AxisOption.B
public string horizontalAxisName = "Horizontal";
public string verticalAxisName = "Vertical";
Vector3 m_StartP
bool m_UseX;
bool m_UseY;
CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualA
CrossPlatformInputManager.VirtualAxis m_VerticalVirtualA
void Start()
mobileJoystickImage = GameObject.Find("MobileJoystick").GetComponent&Image&();
arrowImage = GameObject.Find("ArrowImage").GetComponent&Image&();
backgroundImage = GameObject.Find("BackgroundImage").GetComponent&Image&();
arrowImage.enabled = false;
backgroundImage.enabled = false;
void OnEnable()
m_StartPos = transform.localP
CreateVirtualAxes();
void UpdateVirtualAxes(Vector3 value)
var delta = value - m_StartP
delta /= MovementR
if (m_UseX)
m_HorizontalVirtualAxis.Update(delta.x);
if (m_UseY)
m_VerticalVirtualAxis.Update(delta.y);
void CreateVirtualAxes()
m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);
if (m_UseX)
m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
if (m_UseY)
m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
public void OnDrag(PointerEventData data)
arrowImage.enabled = true;
backgroundImage.enabled = true;
Vector3 newPos = Vector3.
float angles = Mathf.Atan2(data.position.y - m_StartPos.x, data.position.x - m_StartPos.y) * Mathf.Rad2D
#region 四个方向
#endregion
#region 八个方向
if (angles & 67.5 && angles & 112.5)
arrowImage.sprite = sourceImage[0];
else if (angles & 112.5 && angles & 157.5)
arrowImage.sprite = sourceImage[4];
else if (angles & 157.5 && angles & 180 || angles & -180 && angles & -157.5)
arrowImage.sprite = sourceImage[2];
else if (angles & -157.5 && angles & -112.5)
arrowImage.sprite = sourceImage[5];
else if (angles & -112.5 && angles & -67.5)
arrowImage.sprite = sourceImage[1];
else if (angles & -67.5 && angles & -22.5)
arrowImage.sprite = sourceImage[7];
else if (angles & -22.5 && angles & 22.5)
arrowImage.sprite = sourceImage[3];
else if (angles & 22.5 && angles & 67.5)
arrowImage.sprite = sourceImage[6];
#endregion
if (m_UseX)
int delta = (int)(data.position.x - m_StartPos.x);
delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
newPos.x =
if (m_UseY)
int delta = (int)(data.position.y - m_StartPos.y);
delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
newPos.y =
transform.position = new Vector3(m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);
UpdateVirtualAxes(transform.position);
public void OnPointerUp(PointerEventData data)
mobileJoystickImage.sprite = sourceImage[8];
arrowImage.enabled = false;
backgroundImage.enabled = false;
transform.position = m_StartP
UpdateVirtualAxes(m_StartPos);
public void OnPointerDown(PointerEventData data) { }
void OnDisable()
if (m_UseX)
m_HorizontalVirtualAxis.Remove();
if (m_UseY)
m_VerticalVirtualAxis.Remove();
还有就是如果想要joystick的按钮有动态的显示,比如按下之后高亮,或者开始隐藏,点击之后出现,或者拖动按钮出位置之后隐藏这些功能的话可以添加 UGUI的Button组件
Normal Color 没有点击的时候的颜色
Highlighted Color高亮显示
Pressed Color按压的时候的颜色
Disabled Color 不在点击状态的时候的颜色
Multiplier 颜色乘数
Fade Duration 淡入淡出持续时间
设置这些颜色的alpha的值就可以了
对了,还有第三人称控制器
有两个预制体,两个预制体不同的地方在于一个是AI有NavMeshAgent控制器
AIThirdPersonController
重要组件 Animator、Rigidbody 、CapsuleCollider、NavMeshAgent、AICharacterControl、ThirdPersonCharactterr
AICharacterControl脚本
using UnityE
namespace UnityStandardAssets.Characters.ThirdPerson
[RequireComponent(typeof (NavMeshAgent))]
[RequireComponent(typeof (ThirdPersonCharacter))]
public class AICharacterControl : MonoBehaviour
public NavMeshAgent agent { get; private set; }
public ThirdPersonCharacter character { get; private set; }
private void Start()
agent = GetComponentInChildren&NavMeshAgent&();
character = GetComponent&ThirdPersonCharacter&();
agent.updateRotation = false;
agent.updatePosition = true;
private void Update()
if (target != null)
agent.SetDestination(target.position);
character.Move(agent.desiredVelocity, false, false);
character.Move(Vector3.zero, false, false);
public void SetTarget(Transform target)
this.target =
ThirdPersonCharacter脚本
using UnityE
namespace UnityStandardAssets.Characters.ThirdPerson
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Animator))]
public class ThirdPersonCharacter : MonoBehaviour
[SerializeField] float m_MovingTurnSpeed = 360;
[SerializeField] float m_StationaryTurnSpeed = 180;
[SerializeField] float m_JumpPower = 12f;
[Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f;
[SerializeField] float m_RunCycleLegOffset = 0.2f;
[SerializeField] float m_MoveSpeedMultiplier = 1f;
[SerializeField] float m_AnimSpeedMultiplier = 1f;
[SerializeField] float m_GroundCheckDistance = 0.1f;
Rigidbody m_R
Animator m_A
bool m_IsG
float m_OrigGroundCheckD
const float k_Half = 0.5f;
float m_TurnA
float m_ForwardA
Vector3 m_GroundN
float m_CapsuleH
Vector3 m_CapsuleC
CapsuleCollider m_C
void Start()
m_Animator = GetComponent&Animator&();
m_Rigidbody = GetComponent&Rigidbody&();
m_Capsule = GetComponent&CapsuleCollider&();
m_CapsuleHeight = m_Capsule.
m_CapsuleCenter = m_Capsule.
m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
m_OrigGroundCheckDistance = m_GroundCheckD
public void Move(Vector3 move, bool crouch, bool jump)
if (move.magnitude & 1f) move.Normalize();
move = transform.InverseTransformDirection(move);
CheckGroundStatus();
move = Vector3.ProjectOnPlane(move, m_GroundNormal);
m_TurnAmount = Mathf.Atan2(move.x, move.z);
m_ForwardAmount = move.z;
ApplyExtraTurnRotation();
if (m_IsGrounded)
HandleGroundedMovement(crouch, jump);
HandleAirborneMovement();
ScaleCapsuleForCrouching(crouch);
PreventStandingInLowHeadroom();
UpdateAnimator(move);
void ScaleCapsuleForCrouching(bool crouch)
if (m_IsGrounded && crouch)
if (m_Crouching) return;
m_Capsule.height = m_Capsule.height / 2f;
m_Capsule.center = m_Capsule.center / 2f;
m_Crouching = true;
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_H
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength))
m_Crouching = true;
m_Capsule.height = m_CapsuleH
m_Capsule.center = m_CapsuleC
m_Crouching = false;
void PreventStandingInLowHeadroom()
if (!m_Crouching)
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_H
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength))
m_Crouching = true;
void UpdateAnimator(Vector3 move)
m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
m_Animator.SetBool("Crouch", m_Crouching);
m_Animator.SetBool("OnGround", m_IsGrounded);
if (!m_IsGrounded)
m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
float runCycle =
Mathf.Repeat(
m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
float jumpLeg = (runCycle & k_Half ? 1 : -1) * m_ForwardA
if (m_IsGrounded)
m_Animator.SetFloat("JumpLeg", jumpLeg);
if (m_IsGrounded && move.magnitude & 0)
m_Animator.speed = m_AnimSpeedM
m_Animator.speed = 1;
void HandleAirborneMovement()
Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.
m_Rigidbody.AddForce(extraGravityForce);
m_GroundCheckDistance = m_Rigidbody.velocity.y & 0 ? m_OrigGroundCheckDistance : 0.01f;
void HandleGroundedMovement(bool crouch, bool jump)
if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z);
m_IsGrounded = false;
m_Animator.applyRootMotion = false;
m_GroundCheckDistance = 0.1f;
void ApplyExtraTurnRotation()
float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
public void OnAnimatorMove()
if (m_IsGrounded && Time.deltaTime & 0)
Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaT
v.y = m_Rigidbody.velocity.y;
m_Rigidbody.velocity =
void CheckGroundStatus()
RaycastHit hitI
#if UNITY_EDITOR
Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
m_GroundNormal = hitInfo.
m_IsGrounded = true;
m_Animator.applyRootMotion = true;
m_IsGrounded = false;
m_GroundNormal = Vector3.
m_Animator.applyRootMotion = false;
ThirdPersonController
重要组件 Animator、Rigidbody 、CapsuleCollider、ThirdPersonUserControl、ThirdPersonCharactterr
ThiredPersonUserControl脚本
using UnityE
using UnityStandardAssets.CrossPlatformI
namespace UnityStandardAssets.Characters.ThirdPerson
[RequireComponent(typeof (ThirdPersonCharacter))]
public class ThirdPersonUserControl : MonoBehaviour
private ThirdPersonCharacter m_C
private Transform m_C
private Vector3 m_CamF
private Vector3 m_M
private bool m_J
private void Start()
if (Camera.main != null)
m_Cam = Camera.main.
Debug.LogWarning(
"Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.");
m_Character = GetComponent&ThirdPersonCharacter&();
private void Update()
if (!m_Jump)
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
private void FixedUpdate()
float h = CrossPlatformInputManager.GetAxis("Horizontal");
float v = CrossPlatformInputManager.GetAxis("Vertical");
bool crouch = Input.GetKey(KeyCode.C);
if (m_Cam != null)
m_CamForward = Vector3.Scale(m_Cam.forward, new Vector3(1, 0, 1)).
m_Move = v*m_CamForward + h*m_Cam.
m_Move = v*Vector3.forward + h*Vector3.
#if !MOBILE_INPUT
if (Input.GetKey(KeyCode.LeftShift)) m_Move *= 0.5f;
m_Character.Move(m_Move, crouch, m_Jump);
m_Jump = false;
ThirdPersonCharacter脚本
using UnityE
namespace UnityStandardAssets.Characters.ThirdPerson
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Animator))]
public class ThirdPersonCharacter : MonoBehaviour
[SerializeField] float m_MovingTurnSpeed = 360;
[SerializeField] float m_StationaryTurnSpeed = 180;
[SerializeField] float m_JumpPower = 12f;
[Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f;
[SerializeField] float m_RunCycleLegOffset = 0.2f;
[SerializeField] float m_MoveSpeedMultiplier = 1f;
[SerializeField] float m_AnimSpeedMultiplier = 1f;
[SerializeField] float m_GroundCheckDistance = 0.1f;
Rigidbody m_R
Animator m_A
bool m_IsG
float m_OrigGroundCheckD
const float k_Half = 0.5f;
float m_TurnA
float m_ForwardA
Vector3 m_GroundN
float m_CapsuleH
Vector3 m_CapsuleC
CapsuleCollider m_C
void Start()
m_Animator = GetComponent&Animator&();
m_Rigidbody = GetComponent&Rigidbody&();
m_Capsule = GetComponent&CapsuleCollider&();
m_CapsuleHeight = m_Capsule.
m_CapsuleCenter = m_Capsule.
m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
m_OrigGroundCheckDistance = m_GroundCheckD
public void Move(Vector3 move, bool crouch, bool jump)
if (move.magnitude & 1f) move.Normalize();
move = transform.InverseTransformDirection(move);
CheckGroundStatus();
move = Vector3.ProjectOnPlane(move, m_GroundNormal);
m_TurnAmount = Mathf.Atan2(move.x, move.z);
m_ForwardAmount = move.z;
ApplyExtraTurnRotation();
if (m_IsGrounded)
HandleGroundedMovement(crouch, jump);
HandleAirborneMovement();
ScaleCapsuleForCrouching(crouch);
PreventStandingInLowHeadroom();
UpdateAnimator(move);
void ScaleCapsuleForCrouching(bool crouch)
if (m_IsGrounded && crouch)
if (m_Crouching) return;
m_Capsule.height = m_Capsule.height / 2f;
m_Capsule.center = m_Capsule.center / 2f;
m_Crouching = true;
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_H
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength))
m_Crouching = true;
m_Capsule.height = m_CapsuleH
m_Capsule.center = m_CapsuleC
m_Crouching = false;
void PreventStandingInLowHeadroom()
if (!m_Crouching)
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_H
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength))
m_Crouching = true;
void UpdateAnimator(Vector3 move)
m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
m_Animator.SetBool("Crouch", m_Crouching);
m_Animator.SetBool("OnGround", m_IsGrounded);
if (!m_IsGrounded)
m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
float runCycle =
Mathf.Repeat(
m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
float jumpLeg = (runCycle & k_Half ? 1 : -1) * m_ForwardA
if (m_IsGrounded)
m_Animator.SetFloat("JumpLeg", jumpLeg);
if (m_IsGrounded && move.magnitude & 0)
m_Animator.speed = m_AnimSpeedM
m_Animator.speed = 1;
void HandleAirborneMovement()
Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.
m_Rigidbody.AddForce(extraGravityForce);
m_GroundCheckDistance = m_Rigidbody.velocity.y & 0 ? m_OrigGroundCheckDistance : 0.01f;
void HandleGroundedMovement(bool crouch, bool jump)
if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z);
m_IsGrounded = false;
m_Animator.applyRootMotion = false;
m_GroundCheckDistance = 0.1f;
void ApplyExtraTurnRotation()
float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
public void OnAnimatorMove()
if (m_IsGrounded && Time.deltaTime & 0)
Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaT
v.y = m_Rigidbody.velocity.y;
m_Rigidbody.velocity =
void CheckGroundStatus()
RaycastHit hitI
#if UNITY_EDITOR
Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
m_GroundNormal = hitInfo.
m_IsGrounded = true;
m_Animator.applyRootMotion = true;
m_IsGrounded = false;
m_GroundNormal = Vector3.
m_Animator.applyRootMotion = false;
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11814次
排名:千里之外
原创:52篇
转载:24篇
(5)(1)(22)(28)(20)

我要回帖

更多关于 iphone街霸4隐藏人物 的文章

 

随机推荐