查看: 1397|回复: 0
打印 上一主题 下一主题

unity虚拟视觉效果创建(二)

[复制链接]

5552

主题

2

听众

8万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
11

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-6-11 14:58:30 |只看该作者 |倒序浏览
Showing multiple graphs
Just one graph is a little boring. It would be nice if we had multiple graphs to show. All that's needed is different ways to compute p.y, the rest of the code can stay the same. Let's make this explicit by extracting the code that computes p.y and put it in its own method, which we'll call Linear. All this method does is mimic the mathematical function f(x) = x. We're making this method static because it doesn't require an object to function. All it needs is an input value.What does return do?Does it need to be static?

void Update () {

if(currentResolution != resolution){

CreatePoints();

}

for(int i = 0; i < resolution; i++){

Vector3 p = points.position;

p.y = Linear(p.x);

points.position = p;

Color c = points.color;

c.g = p.y;

points.color = c;

}

emitter.particles = points;

}

private static float Linear (float x) {

return x;

}

It's easy to add other mathematical functions by creating more methods and calling them instead of Linear. Let's add three new method. The first is Exponential, which calculates f(x) = x2. The second is Parabola, which calculates f(x) = (2x - 1)2. The third is Sine, which calculates f(x) = (sin(2&pi;x) + 1) / 2.What's Mathf?

private static float Linear (float x) {

return x;

}

private static float Exponential (float x) {

return x * x;

}

private static float Parabola (float x){

x = 2f * x - 1f;

return x * x;

}

private static float Sine (float x){

return 0.5f + 0.5f * Mathf.Sin(2 * Mathf.PI * x);

}


Having to change the code each time we want to switch between these three options isn't very handy. Let's create an enumeration type which contains en entry for each function we want to show. We call it FunctionOption, but because we define it inside our class it's officially known as Grapher1.FunctionOption.

Add a public variable named function of the new type. This gives us a nice field in the inspector for selecting functions.

What's an enum?

using UnityEngine;
public class Grapher1 : MonoBehaviour {

public enum FunctionOption {

Linear,

Exponential,

Parabola,

Sine

}

public FunctionOption function;

public int resolution = 10;

private int currentResolution;

private Particle[] points;

private ParticleEmitter emitter;

// methods not shown in this example

}


Selecting a function in the inspector is nice, but it doesn't do anything yet. Each update, we need to decide which method to call based on the value of function. There are various ways to do this and we'll use an array of delegates.

We first define a delegate type for methods that have a single float as both input and output, which corresponds to our function methods. We call it FunctionDelegate. Then we add a static array named functionDelegates and fill it with delegates to our methods, in the same order that we named them in our enumeration.

What's a delegate?Why list the method names twice?

public class Grapher1 : MonoBehaviour {

public enum FunctionOption {

Linear,

Exponential,

Parabola,

Sine

}

private delegate float FunctionDelegate (float x);

private static FunctionDelegate[] functionDelegates = {

Linear,

Exponential,

Parabola,

Sine

};

public FunctionOption function;

public int resolution = 10;

private int currentResolution;

private Particle[] points;

private ParticleEmitter emitter;
// methods not shown in this example

}

Now we can select the desired delegate from the array based on our function variable, by casting it to an integer. We store this delegate in a temporary variable and use it to calculate the value of Y.

void Update () {

if(currentResolution != resolution){

CreatePoints();

}

FunctionDelegate f = functionDelegates[(int)function];

for(int i = 0; i < resolution; i++){

Vector3 p = points.position;

p.y = f(p.x);

points.position = p;

Color c = points.color;

c.g = p.y;

points.color = c;

}

emitter.particles = points;

}

Finally, we can change which function is graphed while in play mode!

Although we need to to recreate the graph each time we select another function, the rest of the time nothing really changes. So it's not required to compute the points each update. However, things change if we introduce time into the functions. As an example, let's change the Sine method so it calculates f(x) = (sin(2&pi;x + &Delta;) + 1) / 2, where &Delta; is equal to the play time. This results in a slowly animating sine wave. Here's the entire script.

using UnityEngine;
public class Grapher1 : MonoBehaviour {

public enum FunctionOption {

Linear,

Exponential,

Parabola,

Sine

}

private delegate float FunctionDelegate (float x);

private static FunctionDelegate[] functionDelegates = {

Linear,

Exponential,

Parabola,

Sine

};

public FunctionOption function;

public int resolution = 10;

private int currentResolution;

private Particle[] points;

private ParticleEmitter emitter;

void Start () {

emitter = GetComponent<articleEmitter>();

CreatePoints();

}

private void CreatePoints () {

if(resolution < 2){

resolution = 2;

}

currentResolution = resolution;

emitter.ClearParticles();

emitter.Emit(resolution);

points = emitter.particles;

float increment = 1f / (resolution - 1);

for(int i = 0; i < resolution; i++){

float x = i * increment;

points.position = new Vector3(x, 0f, 0f);

points.color = new Color(x, 0f, 0f);

}

}

void Update () {

if(currentResolution != resolution){

CreatePoints();

}

FunctionDelegate f = functionDelegates[(int)function];

for(int i = 0; i < resolution; i++){

Vector3 p = points.position;

p.y = f(p.x);

points.position = p;

Color c = points.color;

c.g = p.y;

points.color = c;

}

emitter.particles = points;

}

private static float Linear (float x) {

return x;

}
private static float Exponential (float x) {

return x * x;

}

private static float Parabola (float x){

x = 2f * x - 1f;

return x * x;

}

private static float Sine (float x){

return 0.5f + 0.5f * Mathf.Sin(2 * Mathf.PI * x + Time.timeSinceLevelLoad);

}

}

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2025-6-18 05:01 , Processed in 0.065987 second(s), 28 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部