文章目录
- 前言
- 本文实现的最终效果
- 素材
- 1. 页面素材
- 2. 卡片内容素材地址
- 翻页实现
- 1. 配置我们的canvas参数
- 2. 添加封面和页码
- 3. 翻页效果
- 4. 添加按钮
- 5. 脚本控制
- 6. 运行效果
- 页面内容
- 1. 添加卡片内容
- 2. shader控制卡片背面
- 3. 页面背面显示不同卡片
- 源码
- 参考
- 完结
前言
欢迎来到游戏的书籍之门,一个充满魔力和想象力的世界。在这里,你将体验到一种全新的游戏界面交互方式——翻书。通过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。如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我可能也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~