【Unity3D编程】简易时钟制作

文章来自于catlikecoding,原文作者介绍了如何用Unity制作一个模拟时钟。本文翻译了具体的制作过程。

介绍

在这个教程里,我们写一个简短的C#脚本来模拟时钟的指针,你将会学到:

·        创建对象层次结构

·        创建脚本应用到对象

·        访问命名空间

·        使用update函数

·        旋转基于时间的东西

假设你已经对Unity的编辑器有了基本的了解,只要你玩了几分钟的Unity你就可以开始了。

创建时钟

先创建一个新的Unity工程。默认场景包含一个基于 (0, 1, -10) 、俯视Z轴的相机。为了获得和场景视图相机相似的视角,选择相机,然后从菜单中选择GameObject /Align View to Selected

我们需要一个对象结构来代表时钟,从GameObject /Create Empty创建一个空游戏对象,命名为Clock。为它创建三个子对象,分别命名为Hours Minutes,以及 Seconds,确保它们都在(000)位置。

我们用简单的方块来表示时钟的指针。通过GameObject / CreateOther / Cube为每一个指针创建子cube。时针的位置是(0, 1, 0),大小(0.5, 2, 0.5)。分针的位置是(0, 1.5, 0),大小(0.25, 3, 0.25)。秒针的位置 (0, 2, 0),大小(0.1, 4, 0.1)


激活时钟

激活时钟需要一个脚本。在Project视图里选择Create / C# Script 来创建一个新C#脚本,命名为ClockAnimator。打开这个脚本并清空,这样我们就可以从头开始。

首先我们想从UnityEngine的命名空间使用一些东西,然后声明ClockAnimator的存在。它是一个从MonoBehaviour.继承的公共有效的class 

这为我们提供了最小的类,可以用来创建组件,保存它,然后应用到Clock 对象,这可以从 Project视图拖拽到 Hierarchy 视图,或者通过Add Component 按钮来实现。

using UnityEngine;

public class ClockAnimator : MonoBehaviour {
	
}

为了激活指针,我们需要进入Transform组件,在脚本中为每个指针添加公共Transform变量并保存。这些公共变量将允许你指定对象到编辑器中的组件属性。然后编辑器会抓取对象的Transform组件并指定到变量。选择Clock对象,然后把相应的对象拖拽到新的属性上。

using UnityEngine;

public class ClockAnimator : MonoBehaviour {

    public Transform hours, minutes, seconds;
}


属性为空与填好属性的ClockAnimator

接下来,给脚本添加update函数。这个函数比较特别,每帧都会被调用。我们用它来设置时钟指针的旋转。

保存脚本之后,编辑器就会主要到组件是有更新函数的,并且会展示一个复选框来让我们禁用它,当然我们是不会禁用的。

using UnityEngine;

public class ClockAnimator : MonoBehaviour {

    public Transform hours, minutes, seconds;

    void Update()
    {
        //currently do nothing
    }

}

更新ClockAnimator使其有个复选框

时针每小时旋转 360/12 度,分针每分钟旋转 360/60 度,秒针每秒钟旋转 360/60 度,为了方便起见爱你,我们把这些值定义为私有常数浮点值。

using UnityEngine;

public class ClockAnimator : MonoBehaviour {

    private const float
        hoursToDegrees = 360f / 12f,
        minutesToDegrees = 360f / 60f,
        secondsToDegrees = 360f / 60f;

    public Transform hours, minutes, seconds;

    void Update()
    {
        //currently do nothing
    }

}

每次更新我们都需要知道当下的时间来使其有效。系统命名空间包含DateTime struct,这能完成此项任务。它有一个叫做Now的静态属性,包含当下时间。每次更新都需要抓取他并存储在一个临时变量里。

using UnityEngine;
using System;

public class ClockAnimator : MonoBehaviour {

    private const float
        hoursToDegrees = 360f / 12f,
        minutesToDegrees = 360f / 60f,
        secondsToDegrees = 360f / 60f;

    public Transform hours, minutes, seconds;

    void Update()
    {
        DateTime time = DateTime.Now;
    }
}

为了使指针旋转起来,我们需要改变他们的局部旋转。直接设置指针的localRotation就可以,这要使用四元数。四元数可以定义任意的旋转。

由于我们是俯视Z轴的,而且Unity使用的是左手坐标系统,旋转必须围绕着Z轴的负半轴。

using UnityEngine;
using System;

public class ClockAnimator : MonoBehaviour {

    private const float
        hoursToDegrees = 360f / 12f,
        minutesToDegrees = 360f / 60f,
        secondsToDegrees = 360f / 60f;

    public Transform hours, minutes, seconds;

    void Update()
    {
        DateTime time = DateTime.Now;
        hours.localRotation = Quaternion.Euler(0f, 0f, time.Hour * -hoursToDegrees);
        minutes.localRotation = Quaternion.Euler(0f, 0f, time.Minute * -minutesToDegrees);
        seconds.localRotation = Quaternion.Euler(0f, 0f, time.Second * -secondsToDegrees);
    }

}

时钟展示

改进时钟

出效果了!在play模式下,时钟显示当下时间。然而,它只显示离散的步骤,仅仅像一个电子时钟。让我们加一个选项来使其展示模拟时间。在脚本里添加一个公共布尔变量analog,用它来决定在update函数中应该做些什么。我们可以在编辑其中切换这个值,甚至在play模式下也可以。

using UnityEngine;
using System;

public class ClockAnimator : MonoBehaviour {

    private const float
        hoursToDegrees = 360f / 12f,
        minutesToDegrees = 360f / 60f,
        secondsToDegrees = 360f / 60f;

    public Transform hours, minutes, seconds;

    public bool analog;

    void Update()
    {
        if (analog)
        {
            //currently do nothing
        }
        else
        {

            DateTime time = DateTime.Now;
            hours.localRotation = Quaternion.Euler(0f, 0f, time.Hour * -hoursToDegrees);
            minutes.localRotation = Quaternion.Euler(0f, 0f, time.Minute * -minutesToDegrees);
            seconds.localRotation = Quaternion.Euler(0f, 0f, time.Second * -secondsToDegrees);
        }
    }
}

ClockAnimator允许模拟模式

对于模拟选项,我们需要一个稍有不同的方法。现在我们要使用DateTime.Now.TimeOfDay代替DateTime,这是一个TimeSpan,允许我们访问稍逝的小时、分钟以及秒。由于这些值是双重提供的-双精数浮点-点值-我们需要将其转换成浮点数。

using UnityEngine;
using System;

public class ClockAnimator : MonoBehaviour {

    private const float
        hoursToDegrees = 360f / 12f,
        minutesToDegrees = 360f / 60f,
        secondsToDegrees = 360f / 60f;

    public Transform hours, minutes, seconds;

    public bool analog;

    void Update()
    {
        if (analog)
        {
            TimeSpan timespan = DateTime.Now.TimeOfDay;
            hours.localRotation =
                Quaternion.Euler(0f, 0f, (float)timespan.TotalHours * -hoursToDegrees);
            minutes.localRotation =
                Quaternion.Euler(0f, 0f, (float)timespan.TotalMinutes * -minutesToDegrees);
            seconds.localRotation =
                Quaternion.Euler(0f, 0f, (float)timespan.TotalSeconds * -secondsToDegrees);
        }
        else
        {

            DateTime time = DateTime.Now;
            hours.localRotation = Quaternion.Euler(0f, 0f, time.Hour * -hoursToDegrees);
            minutes.localRotation = Quaternion.Euler(0f, 0f, time.Minute * -minutesToDegrees);
            seconds.localRotation = Quaternion.Euler(0f, 0f, time.Second * -secondsToDegrees);
        }
    }
}
现在时钟能够模拟工作啦


模拟时钟显示



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值