Unity3D 从入门到放弃(五)----射箭游戏

本文是Unity3D系列教程的第五篇,主要介绍如何制作一个射箭小游戏。游戏规则包括5环计分的靶子和无限试射。内容涵盖了箭和靶的实例化、物体形状创建、游戏逻辑及UML图。通过自定义Editor脚本实现了非内置形状的创建,以及各种组件的使用来实现游戏功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Unity3D 从入门到放弃(五)

—-射箭游戏

填坑啊填坑,每周都补上周作业,啥时候才能到头啊= =


作业需求

游戏规则:
设计一个射箭小游戏,点击鼠标射箭:
 靶对象为 5 环,按环计分;
 箭对象,射中后要插在靶上;
 游戏仅一轮,无限 trials;


实例化部分

本次作业有箭,靶两种实例,实现如下:

  1. 箭:
    箭分为三个部分,箭头,箭身,箭尾。
    箭头:通过一个圆锥和一个圆来实现。圆可以由高度为0的圆锥生成。箭头加上Mesh碰撞器并设置为触发器。(圆锥可以通过Editor文件夹中的CreateCone中创造的菜单实现)
    箭身:通过一个圆柱来实现。
    箭尾:通过两个双面四边形实现,由于unity3d默认渲染单面,因此要四个。(四边形可以通过Editor文件夹中的CreateRectangle中创造的菜单实现)
    为了添加重力,箭总体加入一个刚体。
    最后,将制作好的箭加入预设,作为初始物体。

  2. 靶:
    制作六个圆柱体,分别上不同颜色,并将内圈scale.Y的大小稍微调大一点以显示颜色,调整好角度,加上Mesh碰撞器即可。

  3. 文字框:
    通过UI中的Text创建文字框,此处不再阐述。


效果如图:

箭:

箭构造

这里写图片描述

这里写图片描述

靶:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述


打地基部分:

由于这次用的圆锥和四边形都不是unity3d自带的结构,因此需要自己创造。

首先,先创建一个Editor文件夹:(unity3d默认在Editor文件夹中的内容不能挂载,用于实现一些自动调用的脚本)

这里写图片描述

然后,在文件夹内添加CreateCone和CreateRectangle脚本:

这里写图片描述

脚本内容如下:

CreateCone:

/*
 * 描 述:用于创建圆锥的文件,我只是大自然的搬运工
 * 作 者:hza 
 * 创建时间:2017/04/06 13:20:14
 * 版 本:v 1.0
 */

using UnityEngine;
using UnityEditor;
using System.Collections;

public class CreateCone : ScriptableWizard
{
    /**
     * Num Vertices is the number of vertices each end will have.
     * Radius Top is the radius at the top. The center point will be located at (0/0/0).
     * Radius Bottom is the radius at the bottom. The center point will be located at (0/0/Length).(底圆的半径大小)
     * Length is the number of world units long the plane will be (+Z direction).
     * Opening Angle If this is >0, the top radius is set to 0, and the bottom radius is computed depending on the length, so that the given opening angle is created.(貌似是底圆是多少边形,即越大越接近圆形)
     * Outside defines whether the outside is visible (default).
     * Inside defines whether the inside is visible. Set both outside and inside to create a double-sided primitive.
     * Add Collider creates a matching mesh collider for the cone if checked.
     */

    public int numVertices = 10;
    public float radiusTop = 0f;
    public float radiusBottom = 1f;
    public float length = 1f;
    public float openingAngle = 0f; // if >0, create a cone with this angle by setting radiusTop to 0, and adjust radiusBottom according to length;
    public bool outside = true;
    public bool inside = false;
    public bool addCollider = false;

    [MenuItem("GameObject/Create Other/Cone")]
    static void CreateWizard()
    {
        ScriptableWizard.DisplayWizard("Create Cone", typeof(CreateCone));
    }

    void OnWizardCreate()
    {
        GameObject newCone = new GameObject("Cone");
        if (openingAngle > 0 && openingAngle < 180)
        {
            radiusTop = 0;
            radiusBottom = length * Mathf.Tan(openingAngle * Mathf.Deg2Rad / 2);
        }
        string meshName = newCone.name + numVertices + "v" + radiusTop + "t" + radiusBottom + "b" + length + "l" + length + (outside ? "o" : "") + (inside ? "i" : "");
        string meshPrefabPath = "Assets/Editor/" + meshName + ".asset";
        Mesh mesh = (Mesh)AssetDatabase.LoadAssetAtPath(meshPrefabPath, typeof(Mesh));
        if (mesh == null)
        {
            mesh = new Mesh();
            mesh.name = meshName;
            // can't access Camera.current
            //newCone.transform.position = Camera.current.transform.position + Camera.current.transform.forward * 5.0f;
            int multiplier = (outside ? 1 : 0) + (inside ? 1 : 0);
            int offset = (outside && inside ? 2 * numVertices : 0);
            Vector3[] vertices = new Vector3[2 * multiplier * numVertices]; // 0..n-1: top, n..2n-1: bottom
            Vector3[] normals = new Vector3[2 * multiplier * numVertices];
            Vector2[] uvs = new Vector2[2 * multiplier * numVertices];
            int[] tris;
            float slope = Mathf.Atan((radiusBottom - radiusTop) / length); // (rad difference)/height
            float slopeSin = Mathf.Sin(slope);
            float slopeCos = Mathf.Cos(slope);
            int i;

            for (i = 0; i < numVertices; i++)
            {
                float angle = 2 * Mathf.PI * i / numVertices;
                float angleSin = Mathf.Sin(angle);
                float angleCos = Mathf.Cos(angle);
                float angleHalf = 2 * Mathf.PI * (i + 0.5f) / numVertices; // for degenerated normals at cone tips
                float angleHalfSin = Mathf.Sin(angleHalf);
                float angleHalfCos = Mathf.Cos(angleHalf);

                vertices[i] = new Vector3(radiusTop * angleCos, radiusTop * angleSin, 0);
                vertices[i + numVertices] = new Vector3(radiusBottom * angleCos, radiusBottom * angleSin, length);

                if (radiusTop == 0)
                    normals[i] = new Vector3(angleHalfCos * slopeCos, angleHalfSin * slopeCos, -slopeSin);
                else
                    normals[i] = new Vector3(angleCos * slopeCos, angleSin * slopeCos, -slopeSin);
                if (radiusBottom == 0)
                    normals[i + numVertices] = new Vector3(angleHalfCos * slopeCos, angleHalfSin * slopeCos, -slopeSin);
                else
                    normals[i + numVertices] = new Vector3(angleCos * slopeCos, angleSin * slopeCos, -slopeSin);

                uvs[i] = new Vector2(1.0f * i / numVertices, 1);
                uvs[i + numVertices] = new Vector2(1.0f * i / numVertices, 0);

                if (outside && inside)
                {
                    // vertices and uvs are identical on inside and outside, so just copy
                    vertices[i + 2 * numVertices] = vertices[i];
                    vertices[i + 3 * numVertices] = vertices[i + numVertices];
                    uvs[i + 2 * numVertices] = uvs[i];
                    uvs[i + 3 * numVertices] = uvs[i + numVertices];
                }
                if (inside)
                {
                    // invert normals
                    normals[i + offset] = -normals[i];
                    normals[i + numVertices + offset] = -normals[i + numVertices];
                }
            }
            mesh.vertices = vertices;
            mesh.normals = normals;
            mesh.uv = uvs;

            // create triangles
            // here we need to take care of point order, depending on inside and outside
            int cnt = 0;
            if (radiusTop == 0)
            {
                // top cone
                tris = new int[numVertices * 3 * multiplier];
                if (outside)
                    for (i = 0; i < numVertices; i++)
                    {
                        tris[cnt++] = i + numVertices;
                        tris[cnt++] = i;
                        if (i == numVertices - 1)
   
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值