Endlessdaydream/Endless_Unity_Projects: Unity Projects of Endlessdaydram (github.com)https://github.com/Endlessdaydream/Endless_Unity_Projects
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
PlayerCharacter character;
void Start()
{
character = GetComponent<PlayerCharacter>();
}
// Update is called once per frame
void Update()
{
float h = Input.GetAxis("Horizontal");
bool jump = Input.GetButtonDown("Jump");
character.Move(h,jump);
if (Input.GetButtonDown("Fire1"))
{
character.Grab();
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCharacter : Character
{
Transform grabTrans; //正在抓取的物体,没有物体为null
public Transform grabPos; //z抓取物体的点
public void Grab()
{
if (grabTrans==null)
{
//尝试抓箱子
Vector3 start = transform.position + new Vector3(0, 0.7f, 0);
//Debug.DrawLine(start, start + transform.right, Color.red);
RaycastHit hit;
if (Physics.Raycast(start, transform.right, out hit, 1, LayerMask.GetMask("GrabBox")))
{
Transform box = hit.transform;
box.parent = grabPos;
box.localPosition = Vector3.zero;
box.localRotation = Quaternion.identity;
box.GetComponent<Rigidbody>().isKinematic = true;
grabTrans = box;
}
}
else
{
//扔箱子
grabTrans.parent = null;//将物体放回场景中(设置父物体为空,回到一级物体)
grabTrans.GetComponent<Rigidbody>().isKinematic = false;
grabTrans.position = new Vector3(grabTrans.position.x, grabTrans.position.y, 0);
grabTrans.rotation = new Quaternion(grabTrans.rotation.x, 0, grabTrans.rotation.z, 0);
grabTrans = null;
}
}
private void Update()
{
if (grabTrans==null)
{
anim.SetBool("Grab", false);
}
else
{
anim.SetBool("Grab", true);
}
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
CharacterController cc;
protected Animator anim;
Vector3 pendingVelocity;//这一帧移动的向量
bool isGround=false;
public float speed = 6;
public float jumpSpped = 10;
public GameObject deathParticle;//死亡粒子特效
void Start()
{
cc = GetComponent<CharacterController>();
anim = GetComponent<Animator>();
}
public void Move(float h,bool jump)
{
pendingVelocity.x = h * speed;
pendingVelocity.z = 0;
if (Mathf.Abs(h) > 0.1f)
{
//考虑旋转
Quaternion right = Quaternion.LookRotation(Vector3.forward);
Quaternion left = Quaternion.LookRotation(Vector3.back);
if (h>0)
{
//往右转
transform.rotation= Quaternion.Slerp(transform.rotation, right, 0.05f);
}
else
{
//往右转
transform.rotation = Quaternion.Slerp(transform.rotation, left, 0.05f);
}
}
//处理跳跃
if (jump && isGround)
{
//正常跳跃
pendingVelocity.y = jumpSpped;
isGround = false;
}
//考虑下落
if (!isGround)
{
pendingVelocity.y += Physics.gravity.y * 2 * Time.deltaTime;
}
else
{
pendingVelocity.y = 0;
}
cc.Move(pendingVelocity * Time.deltaTime);
//更新动画
UpdateAnim();
//踩踏攻击检测
AttackCheck();
}
private void AttackCheck()
{
Ray ray = new Ray(transform.position, Vector3.down);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 0.1f, LayerMask.GetMask("Cha")))
{
//不打中自身
if (hit.transform==transform)
{
return;
}
//被射线打中的物体是 hit.transform
Character cha = hit.transform.GetComponent<Character>();
cha.TakeDamage();
//反弹
Bounce();
}
}
public void TakeDamage()
{
Destroy(gameObject);
GameObject go = Instantiate(deathParticle, transform.position, Quaternion.identity);
Destroy(go,2);//两秒后删除粒子
}
private void Bounce()
{
pendingVelocity.y = jumpSpped / 2;
}
private void FixedUpdate()
{
isGround = false;
Ray ray = new Ray(transform.position + new Vector3(0, 0.2f, 0), Vector3.down);
Vector3 start = transform.position + new Vector3(0, 0.2f, 0);
//Debug.DrawLine(start, start + new Vector3(0, -0.25f, 0),Color.blue);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 0.25f, LayerMask.GetMask("Default")))
{
isGround = true;
}
}
private void UpdateAnim()
{
anim.SetFloat("Forward", cc.velocity.magnitude / speed);
anim.SetBool("IsGround", isGround);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AIController : MonoBehaviour
{
Character character;
float inputX;//模拟横向输入-1~1
bool jump = false;
public float changrActTime = 2;//改变行动的时间间隔
public float jumpTime = 0.5f;//每个0.5秒尝试跳跃
public float jumpChance = 30;//每次有30%概率跳跃
void Start()
{
character = GetComponent<Character>();
StartCoroutine(ChangeAct());
StartCoroutine(AIJump());
}
// Update is called once per frame
void Update()
{
character.Move(inputX, jump);
jump = false;
}
IEnumerator ChangeAct()
{
while (true)
{
//改变inputX
inputX = Random.Range(-1f, 1f);
yield return new WaitForSeconds(changrActTime);
}
}
IEnumerator AIJump()
{
while (true)
{
int r = Random.Range(0, 100);
if (r<jumpChance)
{
jump = true;
}
yield return new WaitForSeconds(jumpTime);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MobileController : MonoBehaviour
{
PlayerCharacter character;
void Start()
{
character = GetComponent<PlayerCharacter>();
}
// Update is called once per frame
void Update()
{
float h = VirtualContorller.GetAxis(ButtonType.horizontal);
bool jump = VirtualContorller.GetButtonDown(ButtonType.jump);
character.Move(h,jump);
if (VirtualContorller.GetButtonDown(ButtonType.action))
{
character.Grab();
}
}
}