枪支射击类

13 篇文章 0 订阅

枪支射击

1.搭建基本场景。

相关代码:

//登录
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class id : MonoBehaviour
{
public InputField inputid; //账号
public InputField inputpassword; //密码
public Text t; //返回文本

// Use this for initialization
void Start()
{

}

// Update is called once per frame
void Update()
{

}
public void idpassword()
{
    if (inputid.text == "shoot" && inputpassword.text == "123456")
    {
        SceneManager.LoadScene("start");  //输入正确,跳转到开始界面
    }
    else
    {
        t.text = "账号或密码错误";
        t.color = Color.red;  //输入错误,继续保持此界面
    }
}

}

//进度条
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class Load : MonoBehaviour {

private AsyncOperation aync;
public Image load;  //进度条
private int figure = 0;  //已加载的进度
public Text loadtext;  //百分制显示进度数值


// Use this for initialization
void Start () {

    //开启一个协程,它会根据迭代器中yield return 来判断什么时候暂时退出当前函数
    //然后在下一段时间继续执行yield return 后面的函数代码
    //会在第一次运行后一直执行,直到有代码控制它停止
    StartCoroutine("LoadScence"); 

}

IEnumerator LoadScence()  //定义一个迭代器,每一帧返回一次当前的载入进度,同时关闭自动的场景跳转
{
    aync = SceneManager.LoadSceneAsync("shoot");  //要跳转的场景
    aync.allowSceneActivation = false;
    yield return aync;
}


// Update is called once per frame
void Update () {
    
    if (aync == null)  //判断是否有场景正在加载
    {
        return;
    }
    
    int progrssvalue = 0;  //百分制进度
    //当场景加载进度在90%以下时,将数值以整数百分制呈现,当资源加载到90%时就将百分制进度设置为100
    if (aync.progress < 0.9f)
    {
        progrssvalue = (int)aync.progress * 100;
    }
    else
    {
        progrssvalue = 100;
    }

    //对进度条和百分制数据进行更改,已加载进度与百分制进度比较
    if (figure < progrssvalue)
    {
        figure++;
        load.fillAmount = figure / 100f;  //进度条与已加载进度数值保持一致
        loadtext.text = "加载资源中:" +figure.ToString() + "%";
    }

    //一旦进度到达100时,开启自动场景跳转,LoadSceneAsync会加载完剩下的10%的场景资源
    //LoadSceneAsync只能加载90%的场景资源,剩下的10%场景资源要在开启自动场景跳转后才加载
    if (figure == 100)
    {
        aync.allowSceneActivation = true;
    }
}

}

//继续,重玩,退出
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Vtime : MonoBehaviour
{

//时间对场景中所有物体生效,可赋给任一物体

public Button go;  //继续
public Button replay;  //重玩
public Button exit;  //退出

// Use this for initialization
void Start()
{
    Time.timeScale = 1;  //一开始时间正常流逝
    go.gameObject.SetActive(false);  //隐藏
    replay.gameObject.SetActive(false);
    exit.gameObject.SetActive(false);
    go.onClick.AddListener(VClick);  //点击 继续 按钮时,执行函数(游戏继续,时间正常流逝,提示框消失)      
}

public void VClick()
{
    Cursor.visible = false;  //隐藏鼠标
    Time.timeScale = 1;  //时间正常流逝(大于1,时间飞逝,小于1,时间减缓)
    go.gameObject.SetActive(false);  
    replay.gameObject.SetActive(false);
    exit.gameObject.SetActive(false);          
}

// Update is called once per frame
void Update()
{
    if (Input.GetKeyDown(KeyCode.P))
    {
        Cursor.visible = true;  //出现鼠标
        Time.timeScale = 0;  //时间暂停
        go.gameObject.SetActive(true);  //出现
        replay.gameObject.SetActive(true);
        exit.gameObject.SetActive(true);
    }
}

}

//场景转换
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Scene : MonoBehaviour {

// Use this for initialization
void Start () {


}

// Update is called once per frame
void Update () {

}

public void tranid()
{
    SceneManager.LoadScene("id");
}

public void transhoot()
{
    SceneManager.LoadScene("shoot");
}

public void tranload()
{
    SceneManager.LoadScene("load");
}

}

2.开枪射击

鼠标左键按下开火,右键调出十字瞄准器,Q键改变枪支。

相关代码:
//切换枪支,枪支动画效果,生成子弹
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ShootBirth : MonoBehaviour
{

public Transform taget;   //子弹发射口
RaycastHit raycastHit;  //存储发射射线后产生的碰撞信息
public Camera cam;
Animator animator;
public int i=3;  //步枪(m24)剩余子弹数
public Text text;  //剩余子弹提示
public GameObject vM24;  //可连发3颗子弹后再装膛
public GameObject v98k;  //射击一次,装膛一次
bool isbool = true;  //作为切换枪的条件
public PlayerRotation player;  //可调用PlayerRotation脚本


// Use this for initialization
void Start()
{
    Cursor.visible = false;  //隐藏鼠标
    animator = vM24.GetComponent<Animator>();  //一开始为步枪(m24)       
}

// Update is called once per frame
void Update()
{
    //步枪时(m24),true,狙击枪时(98k),false
    if (Input.GetKeyDown(KeyCode.Q))
    {
        if (isbool)
        {
            v98k.SetActive(true);
            vM24.SetActive(false);
            animator = v98k.GetComponent<Animator>();
            text.gameObject.SetActive(false);  //剩余子弹数不需要显示
        }
        else
        {
            v98k.SetActive(false);
            vM24.SetActive(true);
            animator = vM24.GetComponent<Animator>();
            text.gameObject.SetActive(true);
        }
        isbool = !isbool;  //转化枪
        player.Close();  //转换枪时,瞄准器会消失
        player.isbool = true;  //true状态,点击右键时会出现
    }
    text.text = "剩余子弹数:" + i;

    //检查当前动画控制器所播放的动画片段
    //获取动画控制器
    AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(0);
    //如果当前状态机所播放的动画片段是Idle
    if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.Idle"))
    {
        if (Input.GetMouseButtonDown(0))
        {
            if (isbool)   //为步枪状态时(m24),子弹数才减少
            {
                i = i - 1;
            }
            
            animator.SetInteger("shoot", 1);
            Sources.instance.Playaudioclip("Sniper_Shoot");

            //对子弹实例化,赋予和taget一样的位置和角度作为初始值(即在taget处发射子弹)
            GameObject bullet = Instantiate(Resources.Load<GameObject>("zidan"), taget.position, taget.rotation);


            Vector3 hitpoint;  //触碰点
            //从屏幕中间位置发射一条射线
            Ray ray = cam.ScreenPointToRay(new Vector3(Screen.width / 2, Screen.height / 2, 0));
            //检测射线是否触碰到物体
            if (Physics.Raycast(ray, out raycastHit))  //发射一条射线,和物体发生碰撞,碰撞后得到碰撞信息,返回true
            {

                //获取射线与物体触碰的点
                hitpoint = raycastHit.point;

                //使生成的子弹看向触碰点(向触碰点瞄准发射)
                bullet.transform.LookAt(hitpoint);

                //子弹发射口射线路径
                Debug.DrawLine(taget.position, hitpoint, Color.red, 3);  //起点,终点,颜色,时间
                //瞄准点射线路径
                Debug.DrawLine(cam.transform.position, hitpoint, Color.green, 3);
            }
            Destroy(bullet, 3);
        }
    }
   
    if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.Shoot"))
    {
        if (isbool)  //步枪状态(m24),可连续射击
        {
            if (i == 0)  //无子弹时
            {
                animator.SetInteger("shoot", 2);
            }
            if (i > 0)  //有子弹时
            {
                animator.SetInteger("shoot", 0);
            }
        }
        else  //狙击枪状态(98k),射击一次后立即装膛
        {
            animator.SetInteger("shoot", 2);
        }
    }

    if (stateInfo.fullPathHash == Animator.StringToHash("Base Layer.Bolt"))
    {
        animator.SetInteger("shoot", 0);
        player.Close();  //装膛时瞄准器关闭
        player.isbool = true;  //true状态,点击右键时会出现
        Sources.instance.Playaudioclip("Sniper_Bolt");
        if (isbool)   //为步枪状态时(m24),装膛后子弹装满
        {
            i = 3;
        }           
    }
}

}

//子弹移动,攻击敌人
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Bulletmove : MonoBehaviour {

// Use this for initialization
void Start () {

    //给物体一个向前的速度(赋给子弹,将子弹转为预制体)
    GetComponent<Rigidbody>().velocity = transform.forward * 10;  
}

private void OnCollisionStay(Collision collision)
{
    if (collision.gameObject.tag == "bear")  //如果标签为bear
    {
        Destroy(gameObject);  //子弹消失
        collision.gameObject.GetComponent<BearHP>().xuetiao -= 30;   //血量减少30
    }
}

// Update is called once per frame
void Update ()
{
   
    Destroy(gameObject, 3);  //一段时间后消失

}   

}

//音效
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sources : MonoBehaviour {

//一个播放器多个音效
public static Sources instance;   //可在其他脚本中调用
public AudioSource audioSource;  //播放器
public AudioClip[] audioClips;   //音效

Dictionary<string, AudioClip> dictionary = new Dictionary<string, AudioClip>();
// Use this for initialization
void Start () {
    instance = this;
    foreach (AudioClip clip in audioClips)
    {
        dictionary.Add(clip.name, clip);   //将所有名字和音效添加到字典
    }
}

public void Playaudioclip(string audioname)   //播放音效
{
    if (dictionary.ContainsKey(audioname))   //判断字典中的key值是否包含所用音效
    {
        AudioClip clip = dictionary[audioname];
        audioSource.clip = clip;    //若包含则播放此音效
        audioSource.Play();
    }
}

// Update is called once per frame
void Update () {
   
}    

}

3.人物的行走

玩家在自己的坐标空间内向WSAD移动,接触地面可按空格实现跳跃效果。

相关代码:
//人物移动,跳跃
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Playermove : MonoBehaviour {

//WSAD人物移动,空格跳跃

public float speed = 6f;
public float distance = 3.2f;  //射线最大距离(值由物体距离决定,高一点即可)

public AudioSource music;  //播放器
public AudioClip walk;  //走路音效

// Use this for initialization
void Start () {

    music = GetComponent<AudioSource>();  //获取播放器

}

//地面检测
bool Isground()
{
    //以当前物体的中心点为起点,向下发射一条长度为distance的射线,检测是否触碰到碰撞盒(地面),触碰到则为true
    return Physics.Raycast(transform.position, Vector3.down, distance);
}

// Update is called once per frame
void Update () {

    float x = Input.GetAxis("Horizontal");  //AD移动
    float y = Input.GetAxis("Vertical");  //WS移动
    //Sources.instance.Playaudioclip("walk");

    if (Input.GetButtonDown("Vertical"))
    {
        music.clip = walk;  //设置音源
        music.loop = true;  //循环播放
        music.Play();  //播放音源
    }
    if (Input.GetButtonUp("Vertical"))
    {
        music.Pause();  //暂停音频
    }
   
    //人物位移
    transform.Translate(new Vector3(x, 0, y) * Time.deltaTime * speed, Space.Self); //以自身坐标为轴
    if (Input.GetButtonDown("Jump"))  //空格跳跃
    {           
        if (Isground())  //返回值为true时
        {
            GetComponent<Rigidbody>().velocity = transform.up * speed;  //可向上跳跃(加刚体)
        }
    }
}

}

4.枪的上下左右移动

移动鼠标,实现上下左右移动,抬头低头设置一个范围。

相关代码:
//旋转
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerRotation : MonoBehaviour {

//鼠标上下左右滑动,控制视角旋转

public float speed = 6f;
public Camera cam;
float x;
float y;
public GameObject obj;  //瞄准镜

public bool isbool = true;

// Use this for initialization
void Start () {

    x = cam.transform.eulerAngles.x;

}

// Update is called once per frame
void Update () {

    y = Input.GetAxis("Mouse X") * speed;  //人物y轴变化量(鼠标左右滑动)
    x -= Input.GetAxis("Mouse Y") * speed;  //摄像机上下旋转(鼠标上下滑动)
    x = Mathf.Clamp(x, -20, 22);  //旋转范围
    cam.transform.eulerAngles = new Vector3(x, cam.transform.eulerAngles.y, 0);  //摄像机变化值(欧拉角)
    transform.localRotation = transform.localRotation * Quaternion.Euler(0, y, 0);  //人物左右旋转(以y轴为中心旋转)

    if (Input.GetMouseButtonDown(1))  //按鼠标右键进行瞄准器的切换
    {
        if (isbool)
        {
            obj.SetActive(true);
            cam.fieldOfView = 20;  //显示范围
            //摄像机不渲染第8层(在右上角Layer中可知第几层)
            cam.cullingMask = ~(1 << 8);  
        }
        else
        {
            Close();
        }
        isbool = !isbool;
    }

}
public void Close()  //关闭瞄准镜
{
    obj.SetActive(false);
    cam.fieldOfView = 60;
    cam.cullingMask = -1;  //都显示
}

}

5.敌人

设定敌人生命值,受到攻击后减少,直至死亡,敌人死亡后,刷新生成,巡逻效果。

相关代码:
//巡逻
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Bearnav : MonoBehaviour {

//地面定为静态Static(右上角),Window-Navigation-Bake,烘焙地面

private NavMeshAgent meshAgent;  //给追随物体添加组件
public Transform[] transforms;  //为多个目标点建立数组
float time = 0;
int i = 0;  //计目标点个数
public Animator animator;

// Use this for initialization
void Start()
{
    meshAgent = GetComponent<NavMeshAgent>();
    animator.SetBool("move", true);
    meshAgent.SetDestination(transforms[0].position);   //一开始去第一个目标点
}

private void OnCollisionStay(Collision collision)
{
    if (collision.gameObject.tag == "Player")
    {
        animator.SetBool("attack", true);
    }
}
private void OnCollisionExit(Collision collision)
{
    if (collision.gameObject.tag == "Player")
    {
        animator.SetBool("attack", false);
    }
}

// Update is called once per frame
void Update () {
  
    if (Vector3.Distance(meshAgent.nextPosition, meshAgent.destination) < 2f)  //下一步的位置与目标点位置相近,即到达
    {
        animator.SetBool("move", false);  
        time += Time.deltaTime;  //3s时间内等待
        if (time > 3)  //到达3s后,去下一个目标点
        {              
            //随机移动
            i = Random.Range(0, transforms.Length - 1);

            time = 0;
            meshAgent.SetDestination(transforms[i].position);  //下一个目标点的位置
            animator.SetBool("move", true);  //移动到下一个目标点
        }
    }
}

}

//血量
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class BearHP : MonoBehaviour {

public Text text;
public float xuetiao = 100;  //血条数值
public Image green;  //血条绿值
public Image red;

public Transform taget;  //敌人出现处
public GameObject[] Enemys;

// Use this for initialization
void Start () {

}

public void _Enemy()   //生成敌人
{
    GameObject bullet = Instantiate(Resources.Load<GameObject>("Bear"), taget.position, taget.rotation);
    bullet.gameObject.SetActive(true);
    text.gameObject.SetActive(true);
    green.gameObject.SetActive(true);
    red.gameObject.SetActive(true);
    
}

// Update is called once per frame
void Update()
{
    if (xuetiao <= 30)
    {
        xuetiao = 0;  //每次减少30的血值,如果不足30,置为0,防止变成负数
        Destroy(gameObject);   //血值为0,消失
        text.gameObject.SetActive(false);
        green.gameObject.SetActive(false);
        red.gameObject.SetActive(false);
        _Enemy();
        xuetiao = 100;
    }
    green.fillAmount = xuetiao / 100;  //血值绿条与血值数值相对应
    text.text = "敌剩余血量:" + xuetiao;  //在界面上显示血值
}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值