【Unity小技巧】在Unity中实现类似书的功能(附git源码)

前言

欢迎来到游戏的书籍之门,一个充满魔力和想象力的世界。在这里,你将体验到一种全新的游戏界面交互方式——翻书。通过Unity引擎的强大功能,我们成功地将书籍的神奇氛围融入到游戏中,为玩家带来了一种崭新、富有艺术感的页面选择方式。

你可以把这个效果用在任何地方,比如关卡选择,商店,故事介绍,物品背包,成就页面等等,这能极大的丰富你的游戏。

无疑,游戏UI交互是极为重要的,对比死板的页面,他能给玩家一种新颖感,让你的游戏在一开始就抓住每个玩家的心!

本文实现的最终效果

在这里插入图片描述

素材

1. 页面素材

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 卡片内容素材地址

https://www.freepik.com/free-vector/hand-drawn-months-year-element-collection_34654526.htm
在这里插入图片描述

翻页实现

1. 配置我们的canvas参数

防止适配不同的设备分辨率,防止页面变形
具体的介绍可以看我上一篇文章:【Unity小技巧】最简单的UI设置适配方案,萌新必看
在这里插入图片描述

2. 添加封面和页码

在这里插入图片描述

3. 翻页效果

翻页的原理就是修改页码y轴进行旋转翻页
在这里插入图片描述
你会发现现在的旋转点不太正确,物体是绕着轴心旋转的,我们只要把轴心移到要旋转的位置即可
在这里插入图片描述

4. 添加按钮

在这里插入图片描述
上一页按钮直接复制下一页按钮参数,把旋转z轴设未-180即可,切忌不要修改错了,如果修改y轴的值,虽然也能实现一样的页面效果,但是你会发现按钮没办法点击了
在这里插入图片描述

层级结构如下
在这里插入图片描述

5. 脚本控制

添加脚本book

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class book : MonoBehaviour
{
    
    
    // 定义一个序列化字段,表示页面的速度
    [SerializeField] float pageSpeed = 0.5f;
    // 定义一个序列化字段,表示页面的列表
    [SerializeField] List<Transform> pages;
    // 定义一个索引,初始值为-1
    int index = -1;
    // 定义一个布尔值,表示是否旋转,初始值为false
    bool rotate = false;
    // 定义一个序列化字段,表示后退按钮
    [SerializeField] GameObject backButton;
    // 定义一个序列化字段,表示前进按钮
    [SerializeField] GameObject forwardButton;

    private void Start()
    {
    
    
        InitialState();
    }

    // 定义InitialState方法,用于初始化状态
    public void InitialState()
    {
    
    
        // 遍历页面列表,将每个页面的旋转设置为初始状态
        for (int i=0; i<pages.Count; i++)
        {
    
    
            pages[i].transform.rotation=Quaternion.identity;
        }
        // 将第一个页面设置为最后一个子对象
        pages[0].SetAsLastSibling();
        // 将后退按钮设置为不活动状态
        backButton.SetActive(false);

    }

    // 定义RotateForward方法,用于向前旋转页面
    public void RotateForward()
    {
    
    
        // 如果正在旋转,则返回
        if (rotate == true) {
    
     return; }
        // 索引加1
        index++;
        // 定义一个角度,用于向前旋转页面
        float angle = 180; //为了向前旋转页面,需要将旋转设置为绕y轴旋转180度
        // 调用ForwardButtonActions方法
        ForwardButtonActions();
        // 将当前页面设置为最后一个子对象
        pages[index].SetAsLastSibling();
        // 开始协程,进行旋转
        StartCoroutine(Rotate(angle, true));

    }

    // 定义ForwardButtonActions方法,用于处理前进按钮的行为
    public void ForwardButtonActions()
    {
    
    
        // 如果后退按钮不活动,则激活后退按钮
        if (backButton.activeInHierarchy == false)
        {
    
    
            backButton.SetActive(true); //每次向前翻页时,应激活后退按钮
        }
        // 如果当前页面是最后一个页面,则关闭前进按钮
        if (index == pages.Count - 1)
        {
    
    
            forwardButton.SetActive(false); //如果页面是最后一个,则关闭前进按钮
        }
    }

    // 定义RotateBack方法,用于向后旋转页面
    public void RotateBack()
    {
    
    
        // 如果正在旋转,则返回
        if (rotate == true) {
    
     return; }
        // 定义一个角度,用于向后旋转页面
        float angle = 0; //为了向后旋转页面,需要将旋转设置为绕y轴旋转0度
        // 将当前页面设置为最后一个子对象
        pages[index].SetAsLastSibling();
        // 调用BackButtonActions方法
        BackButtonActions();
        // 开始协程,进行旋转
        StartCoroutine(Rotate(angle, false));
    }

    // 定义BackButtonActions方法,用于处理后退按钮的行为
    public void BackButtonActions()
    {
    
    
        // 如果前进按钮不活动,则激活前进按钮
        if (forwardButton.activeInHierarchy == false)
        {
    
    
            forwardButton.SetActive(true); //每次向后翻页时,应激活前进按钮
        }
        // 如果当前页面是第一个页面,则关闭后退按钮
        if (index - 1 == -1)
        {
    
    
            backButton.SetActive(false); //如果页面是第一个,则关闭后退按钮
        }
    }

    // 定义一个协程,用于旋转页面
    IEnumerator Rotate(float angle, bool forward)
    {
    
    
        float value = 0f;
        while (true)
        {
    
    
            // 设置旋转为true
            rotate = true;
            // 定义目标旋转
            Quaternion targetRotation = Quaternion.Euler(0, angle, 0);
            // 增加value的值
            value += Time.deltaTime * pageSpeed;
            // 平滑地旋转页面
            pages[index].rotation = Quaternion.Slerp(pages[index].rotation, targetRotation, value); //平滑地旋转页面
            // 计算给定旋转角度和当前旋转角度之间的角度
            float angle1 = Quaternion.Angle(pages[index].rotation, targetRotation); //计算给定旋转角度和当前旋转角度之间的角度
            // 如果角度小于0.1f,则停止旋转
            if (angle1 < 0.1f)
            {
    
    
                // 如果是向后旋转,则索引减1
                if (forward == false)
                {
    
    
                    index--;
                }
                // 设置旋转为false
                rotate = false;
                break;

            }
            // 返回null,继续下一次循环
            yield return null;

        }
    }
}

挂载脚本,配置参数
在这里插入图片描述
绑定按钮事件
在这里插入图片描述
在这里插入图片描述

6. 运行效果

在这里插入图片描述

页面内容

1. 添加卡片内容

接下来丰富一下我们的页面,我们可以往页面里添加卡片内容
在这里插入图片描述
运行你会发现,虽然我们翻页了,但是上一页的内容出现在了我们下一页的背面,显然这是不符合逻辑的

2. shader控制卡片背面

我们可以写一个shader把卡片的背面进行隐藏,新建one-side.shader

Shader "Unlit/one-side"
{
    
    
    Properties
    {
    
    
        _MainTex ("Texture", 2D) = "white" {
    
    }
        [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float)=0
    }
    SubShader
    {
    
    
        Tags {
    
    "Queue"="Transparent" "RenderType"="Transparent"}
        Lighting Off ZWrite Off
        Cull [_Cull]

        Pass
        {
    
    
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
    
    
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
    
    
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
    
    
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
    
    
                fixed4 col = tex2D(_MainTex, i.uv);
                return col;
            }
            ENDCG
        }
    }
}

新建材质Front,挂载我们的one-side,并配置cull=Back
在这里插入图片描述
给我们所有的卡片挂载材质
在这里插入图片描述
运行效果
在这里插入图片描述

3. 页面背面显示不同卡片

可能你还想在每个页面的背面显示新的卡片内容,这也很简单,只需要新建材质Back,挂载我们的one-side,并配置cull=Front
在这里插入图片描述
页面新增4个内容,挂载我们的Back材质
在这里插入图片描述
运行效果
在这里插入图片描述

源码

https://gitcode.net/unity1/unity-book
在这里插入图片描述

参考

【视频】https://www.youtube.com/watch?v=peJ22VmW7QQ

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,于是最近才开始自习unity。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_36303853/article/details/132450992